イベント イベント: マウスの操作、キーボードの操作、ファイル操作など システムやユーザーからの入力・出力のこと Windowsは、イベントに応じて動作するOS イベントドリブン Windowsのアプリケーションもイベントドリブン
メッセージ 発生したイベントをWindowsやアプリケーションに伝える時に、イベントの内容を表すデータをメッセージという。 メッセージには、 マウスが動かされたことを知らせるメッセージ、 窓が閉じられてその部分を描画しなおすことをしらせるメッセージ などがある。
メッセージの発生 キーボードが操作されたりマウスが動作したときなどのイベントが発生したとき、そのイベントをあらわすメッセージが発生する。 アプリケーションの起動や終了、窓の移動などもイベントであり、やはりメッセージが発生する。 キーボードやマウスの操作に関しては、それらの装置を扱うドライバプログラムが、Windowsに対してメッセージを発生する。
メッセージ処理1 メッセージはまず、Windowsが受け取る。 Windowsは受け取ったメッセージの内容を確認する。 内容がシステム関連の場合はそのまま処理を実行する。 内容がアプリケーション向けの場合は、 そのアプリケーションにメッセージを転送する。
メッセージ処理2 例:マウスが動作中のアプリケーションのボタン1の上にあるときにクリックされた場合 1.マウスの座標とクリックされたことを伝えるメッセージがマウスドライバから発生 2.Windowsがメッセージをうけとる。 3.Windowsはマウスの座標と自分の管理情報から、マウスがクリックされたアプリケーションを特定 4.メッセージをアプリケーションに転送する。 5.アプリケーションはメッセージを受けて、ボタン1がクリックされたことを知る。 6アプリケーションはボタン1がクリックされたときのイベントハンドラを実行する。
アプリケーションでの メッセージ処理1 Windowsのアプリケーション WinMain関数の内部にメッセージループという部分を持っている。 また、メッセージを処理するためのウィンドウプロシージャという関数を持っている。 Windowsからのメッセージは、各アプリケーションのWinMain関数におくられる。
アプリケーションでの メッセージ処理2 メッセージループ の例: メッセージループ の例: while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;
GetMessage()関数 アプリケーションは、キューという箱をもっており、この箱にWindowsからメッセージが送られてくる。メッセージはFIFO(先入れ先だし)で処理される。 GetMessage()関数は、このキューをのぞいてメッセージを確認する。メッセージがなければ、新しいメッセージが届くまで待つ。メッセージがある場合や届いた時は、それをチェックする。 そのメッセージの内容が、アプリケーションの終了であれば、このループを抜けてアプリケーションを終わる。 それ以外のメッセージノ場合は、ループを続ける。
TranslateMessage()関数
DispatchMessage()関数 DispatchMessage()関数は、受け取ったメッセージを、メッセージを処理するためのウィンドウプロシージャという関数に送る。
ウィンドウプロシージャ アプリケーションに届いたメッセージを処理する関数。窓ごとにある。 例: LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0L; }
ウィンドウプロシージャ msgにはDispatchMessage()関数で メッセージループから送られたメッセージが 入る。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0L; } msgにはDispatchMessage()関数で メッセージループから送られたメッセージが 入る。
ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0L; } msgの内容がWM_DESTROY(終了ボタンを押した時のメッセージ)の場合、 PostQuitMessage関数をつかって、WM_QUITメッセージが発行される。 このメッセージがメッセージループで受け取られて、アプリケーションの終了が開始される。
ウィンドウプロシージャ その他のメッセージについては、DefWindowProc()関数で標準的な処理をしている。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0L; } その他のメッセージについては、DefWindowProc()関数で標準的な処理をしている。
ウィンドウプロシージャ BCBの場合 BCBではメッセージ処理をユーザーには見せずにカプセル化してある。 イベントハンドラはヘッダーファイルに自動的に登録される。 登録された時に、対応したメッセージとそのメッセージに対する項目が隠されたウィンドウプロシージャに自動的に記述される。そして、メッセージループはApplication->Run()関数の中で実装されており、ユーザーには見えない。
IE WORD Windows キーボードドライバ マウスドライバ