|
本サイトは移転しました。旧アドレスからのリダイレクトは2025年03月31日(月)まで有効です。
|
🛈 | ✖ |
イベント駆動型プログラミングはイベントを待機し、発生したイベントに従い処理を行うプログラミングパラダイム。
イベント駆動型プログラミングの文脈において"イベント"とはプログラムフローが外部から受け取る情報である。MS-DOSのメモリ常駐型プログラムはINT21H割り込みでイベント駆動を実現していたと見なせる(PC98背景のグラフィック画面でキー押下の度にジャンプするマリオをあなたは覚えているだろうか)。95より古いウインドウズはノンプリエンプティブ・マルチタスクで、オペレーティングシステム含む全プログラムがメモリ空間を共有する単一プロセスでイベントは容易に実現できる。今はプリエンプティブ・マルチタスクで全プログラムはオペレーティングシステム管理下に独立したメモリ空間を持ち、プログラムフローはプロセス(厳密にはスレッド)、外部はオペレーティングシステム含む別プロセス(スレッド)、イベントは何らかのプロセス(スレッド)間通信と見なせる。
ウィンドウズの主要なイベントは"メッセージ"と"カーネルオブジェクト"(C++オブジェクトとは関係ない)であるが、通常はGUIを実現するメッセージベースのイベント駆動プログラミングを扱う。カーネルオブジェクトベースのイベント駆動プログラミングは可能だがその必要性は限られる。カーネルオブジェクトの一つに"イベント"があり、これは一般に"イベント"として総称される物の一つに過ぎない。すなわちプログラミング一般の文脈で"イベント"と"メッセージ"はほぼ同義だが、ウィンドウズAPIの文脈で両者は全くの別物である。
以降、ウィンドウズAPIの文脈で説明する。オペレーティングシステムはGUI操作などをメッセージとしてアプリケーションのメッセージキューへ格納する。プログラムフローはメッセージループでメッセージをキューより取得してその情報に基づき処理を行う。ウィンドウズメッセージは処理を行うウィンドウ(コントロール)ハンドル(識別ID)を持ち、メッセージループは処理をそれへ委ねる(ディスパッチ)。
ウィンドウズメッセージの構造を示す。
メッセージはさらに"通知"(notification)と"メッセージ(狭義)"に分類される。"通知"はオペレーティングシステムがウィンドウ(コントロール)の状態変化(主にはGUI操作)をアプリケーションに送付するもので、メッセージキューに格納されるメッセージは全て"通知"である。例えばWM_MOVEはウィンドウが移動した結果としてメッセージキューに格納され、アプリケーションはウィンドウ移動に伴う処理を行う。"メッセージ(狭義)"はアプリケーションがウィンドウへ送付して操作/情報取得し、例えばWM_SETTEXT/WM_GETTEXTはウィンドウ表示文字列を設定/取得する。このようにアプリケーションから見て両者の送付方向は反対で、イベント駆動にあずかるメッセージは"通知"のみと言う事になる。通常のアプリケーションは"通知"を状態変化したウィンドウへディスパッチする。
PostMessage関数はウィンドウの属するスレッドのメッセージキューに格納(ポスト)し、SendMessage関数はウィンドウに直接メッセージを送付する。アプリケーションは"通知"をポスト/送付してウィンドウの状態変化を模擬できる。アプリケーションは"メッセージ(狭義)"を送付してウィンドウを直接操作する。