![]() |
リスト2●Javaを使ってイベントを記述する例。 ここでは二つのイベントを登録している。一つはボタンがクリックされたときの処理。もう一つは終了イベントが発生したときの処理である。いずれもクラスを登録するという形で実装される。実際にはそのクラスの定められた名前のイベントが呼び出される |
メッセージ・ループはどこに消えた?
さてこのようにプログラムを見ても,どこにも「イベント通知を待つループ」は存在しない。これらは「クラス・ライブラリ」の見えないところですでに実装されているからだ。「ほとんどWin32 APIが見えている」と言われるMFCでさえ,メッセージ・ループ(Windowsにおけるイベント待ちループ)は存在しない(リスト3[拡大表示])。MFCを利用したプロジェクトを生成すると,それぞれメッセージのハンドラを実装するよう指示される。
では実際のメッセージ・ループも見ておこう。ソース・コードそのものはかなり以前のWindowsプログラムのものだが,その基本は変わっていない(リスト4[拡大表示])。こう見ると,Windowsのプログラムは大きく二つに分かれている。メッセージを処理するメッセージ・ハンドラの部分と,メッセージ待ちをする部分である。メッセージ待ちをする部分はもともとプログラム実行の主体となる部分で,「WinMain」というエントリ・ポイント注5)を持つ。
この手続きでメイン・ウインドウの生成とそのウインドウに対するメッセージ・ハンドラの登録,およびメッセージ待ちを実施する。
一方現実に処理を担当するのがメッセージ・ハンドラである。Windowsはイベントが発生すると,各プロセスごとに用意した「メッセージ・キュー」にメッセージを積んでいく。これをメッセージ・ループが取り出す。そして今度は,メッセージの割り当て(dispatch)をWindowsに依頼する。一見ややこしく感じられるかもしれないが,仮にメッセージをメッセージ・ループ部で処理する構造になっていると,複数のウインドウを使ったプログラムの実現が難しくなる。
メッセージはフィールドの値で識別する。Windowsが発行する主なメッセージには,ウインドウの再描画を依頼する「WM_PAINT」,メニュー・コマンドのクリックなどを通知する「WM_COMMAND」,終了処理である「WM_QUIT」などがある。すべてのWindowsのメッセージを知っておく必要はないが,特にMFCを利用する場合などはメッセージそのものと対応しているので,基本的な仕組みは理解しているべきだろう。
「そうですよね。OSがアプリケーションにイベントを通知する仕組みが必要ですよね。今まで見たことなかったですけど」 「今さらそんなところを見る必要もないからね」 「でも,ようやく仕組みが理解できたような気がします」 「仕組みをわかっていると,動作を想像しやすくなるよね。メモリのイメージがあるとポインタが理解しやすいのと一緒かな」 「あの…。ポインタは自信ないんですが…」 「今日はこんなところで。それはまた別の機会にしよう」 |