• 締切済み

CWnd::OnTimerのスレッドの取得

いつもお世話になっております。 1)CWnd::OnTimerのスレッドハンドルを取得したいのですが、CreateThread又はAfxBeginThreadで取得できますか? 2)普通、CreateThreadやAfxBeginTHreadでハンドルを取得できるようですが、なぜ作る関数が取得する機能を果たすのか疑問です。 3)CWnd::OnTimerの中身を見たいのですが、どのようにすれば見ることができますか? 知っている方がいましたら教えて下さい。

みんなの回答

noname#30727
noname#30727
回答No.3

1)MFCらしくは扱えませんが、コールバックが呼ばれるときに作成されるスレッドもGetCurrentThreadで取得する擬似ハンドルでアクセスできると思います。このハンドルは自分自身のスレッドを指す特殊な定数なので、他のスレッドから参照する必要があるのならDuplicateHandleで複製してやる必要があります。でも、コールバックに対して、そのような事はしたことがないので無理かもしれません。 3)デフォルトの動作が必要ない種類のものだから、無いと思います。

COPY_ROBOT4
質問者

お礼

ありがとうございます。 新しい発想を知ることができて、とても勉強になりました。 お忙しい中、本当にありがとうございました。

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.2

1について  CWnd::OnTimerはWin32ネイティブでは::SetTimer()で起動され、WM_TIMERメッセージのハンドラとしてキャッチされます。  ::SetTimer()ではTimerProc関数のポインタを指定できますが、ここに指定したとしても、実際にはメッセージキュー経由で起動されるため、結局の所CWnd::OnTimerfハンドラでは新たなスレッドは起動されていません(ウィンドウプロシージャ内で時間のかかる処理を実行してその時間より短い間隔でTimerイベントを発生させるようにしていれば確認できます)。  なのでCWnd::OnTimerのスレッドハンドルはウィンドウプロシージャのスレッドハンドルそのものです。よってそれを知る事が出来ればスレッドを捕まえる事も出来るでしょう(多分PSAPI(NT/2000)やToolhelp32(9x/Me/2000)を使う事で取得できるかもしれません)。 2について Win32の設計やMFCの設計がそうだから(^^; itohhさんと同じく、仕様だからとしか言えませんねぇ(^^; 3について  ありません。というより実体はWM_TIMERのハンドラですから未定義時は::DefWndProc()に流れるようになっているだけでしょう。 MFCのメッセージハンドラ自体、マクロではなくコンパイラ内で処理されているような感じを受けます。CWnd::OnTimer自体がMFCソース内に無いようですし・・・ # OnTimerのくだり(1について)はたしかProgramming Windowsあたりに載ってたと思います。なんかの書籍からウラを取ったのは確かなんですが、どの書籍かはいまいちはっきりしないので・・・ # CWnd::OnTimerでは新規のスレッドが起きない&メッセージキュー経由なので遅延が発生しやすいので、新規にスレッドを起こしたい場合、timeSetEvent()(マルチメディアAPI)の方を使ってください。こちらの方が精度が高く、メッセージキューを経由せず、独立したスレッドが生成されます。

COPY_ROBOT4
質問者

お礼

ありがとうございました。 2については仕様ということで自分に言い聞かせます。 3についてはOnTimer内でハンドルを変数へ渡し、実装しようと考えました。それができれば関数を使わずにハンドル取得ができるのかと思ってみました。 お忙しい中、ご教授感謝しております。

  • itohh
  • ベストアンサー率45% (210/459)
回答No.1

こんにちは。itohhといいます。 ちょっと、質問の意味がわからないのですが。 (1)について。 SetTimer関数で設定された秒数の経過後にOnTimerイベントが呼び出されるというのでは いけないのでしょうか? (2)について。 それは、「仕様です。」ではダメ? newで作成したオブジェクトの戻り値はオブジェクトのアドレス(ハンドル)ですよね? それと、同様だと思うのですが... (3)について。 中身を見るってどういう事を意味しているのでしょうか? OnTimerイベントのときの処理を書きたい、という意味でしょうか? それならば、クラスウイザードでOnTimerイベントを追加してください。 ソースファイルにOnTimer関数のテンプレートが出来るはずですから、処理を追加 してください。 (注)スレッドには2種類有ります、ワーカースレッドとユーザインターフェース    スレッドです。    ユーザインターフェーススレッドでないと、OnTimerイベントは拾えません。    ワーカースレッドで行いたい場合は、独自のメッセージポンプを実装    しなければいけません。

COPY_ROBOT4
質問者

お礼

いろいろ細かくご教授ありがとうございました。 1つ1つの質問を丁寧に教えていただけたのですが、勉強する時間が長すぎて、不採用になってしまいました。 でも、これから自分なりにゆっくり勉強していきます。 また、その時はよろしくお願いします。 VCを触って早3ヶ月も経つのにわからないことだらけでやになります。愚痴を言ってしまいました。 本当にありがとうございました。