標準 Windows メッセージのハンドラー

標準 Windows メッセージ (WM_) の既定のハンドラーは、CWnd クラスで事前に定義されています。 クラス ライブラリでは、これらのハンドラーの名前をメッセージ名に基づいて設定しています。 たとえば、WM_PAINT メッセージのハンドラーは、CWnd で次のように宣言されています。

afx_msg void OnPaint();

afx_msg キーワードは、ハンドラーを他の CWnd メンバー関数から区別することによって、C++ の virtual キーワードの効果を示唆しています。 ただし、これらの関数は実際には仮想ではないことに注意してください。これらは、代わりにメッセージ マップを通じて実装されます。 メッセージ マップは、C++ 言語の拡張機能にではなく、標準のプリプロセッサ マクロにのみ依存します。 afx_msg キーワードは、前処理後は空白に解決されます。

基底クラスで定義されているハンドラーをオーバーライドするには、単に派生クラスで同じプロトタイプの関数を定義し、ハンドラーのメッセージ マップ エントリを作成します。 独自のハンドラーは、そのクラスの基底クラスにある同じ名前のすべてのハンドラーを "オーバーライド" します。

場合によっては、基底クラスおよび Windows がメッセージを操作できるように、独自のハンドラーが基底クラスのオーバーライドされたハンドラーを呼び出す必要があります。 オーバーライドのどこで基底クラスのハンドラーを呼び出すかは、状況によって異なります。 最初に基底クラスのハンドラーを呼び出す必要がある場合も、最後に呼び出す必要がある場合もあります。 メッセージを自分で処理しないことを選択した場合は、基底クラスのハンドラーを条件付きで呼び出すこともあります。 また、基底クラスのハンドラーを呼び出し、それから返される値または状態に応じて、条件付きで独自のハンドラー コードを実行する必要がある場合もあります。

注意事項

ハンドラーに渡される引数を基底クラスのハンドラーに渡す場合、その引数を変更するのは安全ではありません。 たとえば、OnChar ハンドラーの nChar 引数を変更しようと思う場合があるかもしれません (大文字に変換するなど)。 この動作はほとんど目立ちませんが、この効果を実現する必要がある場合は、代わりに CWnd のメンバー関数 SendMessage を使用します。

特定のメッセージをオーバーライドする適切な方法をどのように判断しますか。クラス ウィザードは、特定のメッセージに対するハンドラー関数 (たとえば、WM_CREATE に対する OnCreate ハンドラー) のスケルトンを記述するときに、推奨される、オーバーライドされるメンバー関数の形式で概要を設計します。 次の例では、ハンドラーが最初に基底クラスのハンドラーを呼び出し、-1 が返されない条件のときにのみ処理を続行することを推奨しています。

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CFormView::OnCreate(lpCreateStruct) == -1)
      return -1;

   // TODO:  Add your specialized creation code here

   return 0;
}

慣例により、これらのハンドラーの名前はプレフィックス "On" で始まります。これらのハンドラーのいくつかは引数を取りませんが、複数の引数を取るハンドラーもあります。 また、戻り値の型が void 以外であるものもあります。 すべての WM_ メッセージの既定のハンドラーは、MFC リファレンスCWnd クラスのメンバー関数として記載されています。それらの名前は、"On" で始まります。CWnd でのメンバー関数宣言には、afx_msg というプレフィックスが付いています。

関連項目

メッセージ ハンドラー関数の宣言