>メインのループ内にこんな監視を入れるようなプログラム
これは普通に行われます。定期的かつ、高頻度で更新しなければならないゲームなんかだと常套手段です。
ただし、GetMessage関数はメッセージ来ない間はブロックするので、その間イベント処理が実行されません。
このため、PeekMessage関数を使います。
while(true)
{
if ( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ) { // メッセージを取得した場合0以外が返る
if (msg.message == WM_QUIT ) break; //終了。メッセージループを抜ける。
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
// メッセージがない場合はイベント処理を行う
if(el::boolEvent){
イベント処理へ
}
}
メッセージループと異なるスレッドからメッセージを送る場合SendMessage関数よりPostMessage関数が推奨されます。
二つの関数はメッセージを送って処理されるまでの仕組みが若干異なります。
表面的な動作的の違いは、SendMessage関数は送ったメッセージが処理されるまでブロックし、PostMessage関数はメッセージを送ったら直ちに返ります。
また、メッセージを使ってスレッド間でやりとりする場合、独自のメッセージを定義しなければなりませんが、これにはRegisterWindowMessage関数を使います。
WM_USER以降の番号で固定で割り当てる方法もありますが、他のライブラリやなんかとバッティングする可能性もあるので汎用性を求めるならあんまりオススメしません。
最後に、ループで処理する場合のイベント通知方法ですが、ブール変数1個ではうまく動かないはずです。
なぜなら、メインスレッド側で、「イベント処理したよ!」という通知をしなければ、「イベント着たよ!」というフラグを解除できず、永久にイベント着たよ状態になってしまいます。
この目的では、とりあえず「イベント同期」という仕組みがウィンドウズにありますので、それを使うことになります。
CreateEvent関数、SetEvent関数、WaitForSingleObject関数あたりを参照してください。
APIの説明はこんなところとして、ループ内で処理するのとメッセージどっちが良いかですが、判断基準の一つは受信したデータをメインループへ送る頻度です。
余りに高頻度にイベント処理が送られると、そのイベントメッセージでメッセージキューが埋まってしまいます。
そうすると、ウィンドウのためのメッセージが処理されづらくなり、反応が悪くなる原因になります。
上のループ内処理の場合、受信スレッドからのイベントを一つ処理するごとに、メッセージを確認しているのでその辺の問題は起こりづらくなります。
わかりやすさとしては、どっちもどっちかなぁ…と。
ただ、ループ内で処理すると、スレッド間同期が絡むと思うのでその辺はメッセージ使うより厄介かもしれません。
投稿日時 - 2011-09-28 15:06:32