• ベストアンサー

メッセージ機構とマルチスレッド

windowsのメッセージは、元のスレッドと関係なしに勝手に実行されますよね? たとえばSetTimerを呼びだした状態でウィンドウプロシージャ内で case WM_TIMER:    MessageBox(NULL,"","",MB_OK);    break; とすれば、メッセージボックスを閉じようが、閉じまいが一定時間ごとに、新たにメッセージボックスが生成されます。 しかし、Win32の本などを見ると、プロシージャからただのグローバル変数にアクセスするなど、通常のマルチスレッドではやってはいけないとされる事を平気でやっています。 この点で、マルチスレッドとメッセージ機構はどのように違うのか、ご存知の方、教授お願いします。 ナンセンスな疑問でしたらすいません。

質問者が選んだベストアンサー

  • ベストアンサー
  • ninigi
  • ベストアンサー率43% (10/23)
回答No.2

  ウィンドウメッセージは全て、そのウィンドウを作成したスレッドで実行されます。 このメッセージ機構はマルチタスクの再入ではなく、シングルタスクの再帰呼び出しをイメージした方が良いでしょう。   スレッドが作成した全てのウィンドウに宛てられたメッセージは、そのスレッドのメッセージキューに一緒くたに格納されます。 ご質問のケースの場合、MessageBox( )はメッセージボックスを表示した後OKボタンのクリックを検出するためのGetMessage( )/DispatchMessage( )のメッセージループを関数内に持っています。このメッセージループでメインウィンドウに宛てられたWM_TIMERが取り出されてメインウィンドウのプロシージャが呼び出され2つめのメッセージボックスが表示されます。つまりMessageBox( )呼び出しの中から再度ウィンドウプロシージャが呼び出されている再帰呼び出しの構造になっているのです。   MessageBox( )以外でもUpdateWindow( )やMoveWindow( )、SetScrollInfo( )など多くのウィンドウ操作系のAPIで、関数内部でメッセージが発行されてウィンドウプロシージャが再帰呼び出しされています。  

qOat
質問者

お礼

丁寧な回答ありがとうございます。 ずっと疑問に思っていたことが、氷解しました。 ありがとうございます。

その他の回答 (1)

回答No.1

Windowsのメッセージ機構は,特定のスレッド上で動きます。 マルチスレッド的には動きません。 ユーザーがメッセージループを明示的に書かないとメッセージはウィンドウプロシージャまで届きません。 ウィンドウメッセージはウィンドウを作成したスレッドへ届くためです。 MessageBox APIやDialogBox APIなどは,関数内部にメッセージループを持っているため, 呼び出し元のスレッドへのメッセージが問題なく呼び出されます。 http://msdn2.microsoft.com/en-us/library/ms644994.aspx#modal_boxes いろいろなところでGetCurrentThreadId APIを呼び出してみると,処理しているスレッドが変化していないことがわかるかと。

qOat
質問者

お礼

迅速な回答ありがとうございます。 そういうことでしたか。 疑問が晴れました。