テクニカル ノート 6: メッセージ マップ

この MFC メッセージ マップ機能について説明します。

問題

Microsoft Windows は、そのメッセージング機能を使用してウィンドウ クラスの仮想関数は基本的には何を実装します。多数のメッセージを扱うために、Windows メッセージごとに仮想関数を提供する結果、限りなく大きく vtable で。

また、以来、時間をかけて、システム定義の Windows メッセージの数を変更し、特定のアプリケーションがいくつか、独自の Windows メッセージを定義する場合は、メッセージ マップ機構は既存のコードを破壊からインターフェイスの変更を防ぐことができます間接レベルを提供します。

概要

MFC は、従来の Windows プログラムではウィンドウに送信されるメッセージを処理するために switch ステートメントの代替を提供します。メッセージ ウィンドウで処理する場合は、適切なメンバ関数が自動的に呼び出されますようにメンバー関数へのメッセージからマッピングを定義することがあります。このメッセージ マップ機能の仮想関数に類似するように設計されていますが、C++ の仮想関数ができません追加の利点があります。

メッセージ マップの定義

DECLARE_MESSAGE_MAPマクロ 3 つのメンバーは、クラスの宣言します。

このマクロは、メッセージ マップを使用して、クラスの宣言に配置する必要があります。規約では、クラス宣言の最後には。たとえば:

cMyWnd クラス: パブリック CMyParentWndClass{特価;//私のもの.保護。//{{AFX_MSG(CMyWnd)afx_msg void OnPaint();//}}AFX_MSGDECLARE_MESSAGE_MAP()}(&N)

これは、新しいクラスを作成するときに AppWizard と ClassWizard で生成された形式です。・ ・ {{と//}} ClassWizard の角かっこが必要な。

メッセージ マップのテーブルは、メッセージ マップ エントリに展開するマクロのセットを定義されています。テーブルこのメッセージ マップによって処理されるクラスと未処理のメッセージが渡される親クラスを定義します、 BEGIN_MESSAGE_MAPマクロ呼び出しを開始します。テーブル、 END_MESSAGE_MAPマクロの呼び出しの終了します。

これら 2 つのマクロの呼び出しの間は、このメッセージ マップによって処理される各メッセージのエントリです。マクロのフォームは、メッセージのエントリが生成されます (xxx は、メッセージの名前です) の ON_WM_xxx をすべて標準の Windows メッセージをしています。

標準の関数シグネチャは各 Windows メッセージのパラメーターを展開し、型の安全性を提供するために定義されています。これらの署名は、AFXWIN ファイルにあります。H CWnd の宣言は。それぞれ、単語afx_msgマークされています。

特価;ClassWizard をメッセージ マップ ハンドラーの宣言ではafx_msgキーワードを使用することが必要です。(&N)。

これらの関数のシグネチャは、単純な規則を使用して派生しました。関数の名前は、常に"On"で始まります。これは、Windows メッセージを削除、wm _ の名前とだけが続きます各単語の最初の文字を大文字します。パラメーターの順序が続きます wParam はLOWORD (lParamHIWORD(lParam)。未使用のパラメーターは渡されません。MFC クラスにラップされたすべてのハンドルは、適切な MFC オブジェクトへのポインターに変換されます。次の例、 WM_PAINTメッセージを処理し、CMyWnd が発生する方法を示しています:: OnPaint呼び出される関数

BEGIN_MESSAGE_MAP (CMyWnd、CMyParentWndClass)特価;//{{AFX_MSG_MAP(CMyWnd)ON_WM_PAINT()//}}AFX_MSG_MAPEND_MESSAGE_MAP()(&N)

メッセージ マップのテーブルは、関数またはクラス定義のスコープ外定義する必要があります。それは、extern"C"ブロック内で配置してはなりません。

特価;ClassWizard の間にある、メッセージ マップ エントリを編集する、・ ・ {{と//}} コメント ブラケット(&N)。

ユーザー定義の Windows メッセージ

ユーザー定義メッセージをメッセージ マップにON_MESSAGEマクロを使用してに含まれることがあります。このマクロは、メッセージ数と、フォームのメンバー関数を受け取ります:

特価;//のクラス宣言内afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);たとえば。# define WM_MYMESSAGE (WM_USER + 100)BEGIN_MESSAGE_MAP (CMyWnd、CMyParentWndClass)ON_MESSAGE (WM_MYMESSAGE、OnMyMessage)END_MESSAGE_MAP()(&N)

この例では、Windows のメッセージ id は、ユーザー定義メッセージの基本にある標準WM_USERから派生カスタム メッセージ ハンドラーを確立します。このハンドラーにコードをよう呼び出す可能性があります。:

CWnd ※ pWnd =...;pWnd gt;SendMessage(WM_MYMESSAGE)(&G)

このアプローチを使用してユーザー定義メッセージの範囲 WM_USER 0x7fff 〜 の範囲である必要があります。

特価;ClassWizard では、ClassWizard のユーザー インターフェイスから入力するON_MESSAGEハンドラー ルーチンをサポートしていません: あなたは、Visual C エディターからそれらを手動で入力する必要があります。入力後、ClassWizard これらのエントリを解析し、他のメッセージ マップ エントリと同様に参照することができます。(&N)。

登録済み Windows メッセージ

:: RegisterWindowMessage関数を使用して、システム全体で一意であることが保証されますが新しいウィンドウ メッセージを定義します。マクロON_REGISTERED_MESSAGEはこれらのメッセージを処理するために使用されます。このマクロを受け取り、登録済みの windows を含む近い UINT 変数の名前のメッセージ id。たとえば

cMyWnd クラス: パブリック CMyParentWndClass{パブリック。特価;CMyWnd();//{{AFX_MSG(CMyWnd)afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);//}}AFX_MSGDECLARE_MESSAGE_MAP()};静的 UINT の近く WM_FIND = RegisterWindowMessage("COMMDLG_FIND");BEGIN_MESSAGE_MAP (CMyWnd、CMyParentWndClass)//{{AFX_MSG_MAP(CMyWnd)ON_REGISTERED_MESSAGE (WM_FIND、OnFind)//}}AFX_MSG_MAPEND_MESSAGE_MAP()(&N)

Windows メッセージ ID 変数 (上記の例では、WM_FIND) の登録がON_REGISTERED_MESSAGEの実装方法のため、近くの変数をする必要があります。

このアプローチを使用してユーザー定義メッセージの範囲で 0xc000 から 0 xffff になります。

特価;ClassWizard は、ClassWizard のユーザー インターフェイスから入力ON_REGISTERED_MESSAGEハンドラー ルーチンをサポートしていません、あなたは、テキスト エディターからそれらを手動で入力する必要があります。入力後、ClassWizard これらのエントリを解析し、他のメッセージ マップ エントリと同様に参照することができます。(&N)。

コマンド メッセージ

メニューおよびアクセラレータからのコマンド メッセージは、メッセージ マップはON_COMMANDマクロで処理されます。このマクロには、メンバー関数だけでなく、コマンド ID を受け取ります。WParam等しい ID、メンバー関数によって処理される、指定されたコマンドを特定のWM_COMMANDメッセージのみ、メッセージ マップ エントリで指定します。コマンド ハンドラーのメンバー関数はパラメーターを受け取らず、void を返します。マクロは、フォームをが:

 ON_COMMAND (id、memberFxn)

コマンド更新メッセージはON_COMMANDハンドラーと同じ機構を通じてルーティングされます。ON_UPDATE_COMMAND_UIマクロが使用されます。コマンド更新ハンドラーのメンバー関数は、1 つのパラメーターは、 CCmdUIオブジェクトへのポインターを取る、void を返します。マクロは、フォームをが

ON_UPDATE_COMMAND_UI (id、memberFxn)

拡張形式のコマンド メッセージ ハンドラーは、高度な使用です。ON_COMMAND_EXマクロは、代わりに使用され、はON_COMMAND機能のスーパー セットを提供します。拡張版のコマンド ハンドラー メンバー関数は、1 つのパラメーターは、コマンド ID を含む、UINT を取るし、bool 値を返します。BOOL 戻り値は、コマンドが処理されたことを示す TRUE にする必要があります、それ以外の場合ルーティング他コマンド ターゲット オブジェクトを続ける。

上記のフォームの例:

高度な使用がON_COMMAND_RANGEON_COMMAND_RANGE_EXコマンドの範囲は、1 つのコマンド ハンドラーを処理することができますのためにも使用できます。これらのマクロの詳細については製品ドキュメントを参照します。

特価;ClassWizard 作成ON_COMMANDおよびON_UPDATE_COMMAND_UIハンドラー、サポートしていますが、 ON_COMMAND_EXまたはON_COMMAND_RANGEのハンドラーの作成をサポートしていません。ただし、クラス ウィザードが解析し、3 つのコマンド ハンドラーのすべてのバリエーションを参照することができます。(&N)。

コントロール通知メッセージ

ウィンドウの子コントロールからが余分なビット情報には、メッセージの送信がメッセージ マップ エントリ: コントロールの id。(1) BN_CLICKED などコントロール通知コード (lParam の上位ワード) は、メッセージ マップ エントリで指定された通知コードと一致する (2) コントロール ID (wParam) がメッセージ マップ エントリで指定されたコントロールの ID と一致する場合にのみ、メッセージ マップ エントリで指定されたメッセージ ハンドラーが呼び出されます。

カスタム コントロール通知メッセージは、 ON_CONTROLマクロを使用して、カスタム通知コードとメッセージ マップ エントリを定義することがあります。このマクロはフォームをしています。

ON_CONTROL (wNotificationCode、id、memberFxn)

コントロールの範囲から特定のコントロール通知を同じハンドラーを処理すると、一連の高度な使用法を使用できます。

ClassWizard では、ユーザー インターフェイスにはON_CONTROLと、一連のハンドラーを作成はサポートしていない;あなたは、これらはテキスト エディターからを手動で入力する必要があります。入力後、ClassWizard これらのエントリを解析し、ちょうどどんなその他メッセージ マップ エントリのように参照することができます。

Windows コモン コントロールのより強力なWM_NOTIFY複雑なコントロールの通知に使用します。このバージョンの MFC は、この新しいメッセージON_NOTIFYON_NOTIFY_RANGEマクロを直接サポートしています。これらのマクロの詳細については製品ドキュメントを参照します。

番号順テクニカル ノート|nbsp;カテゴリ別テクニカル ノート(&N)

Index