MFCでメッセージをトラップする-違いは何ですか?
質問
関数OnSize(..)に対するMFCの次の2つのメッセージトラップの違いは何か(あるとしても)疑問に思っていました。
1-メッセージマップ経由:
BEGIN_MESSAGE_MAP(CClassWnd, CBaseClassWnd)
...
ON_WM_SIZE()
..
END_MESSAGE_MAP()
2-afx_message経由:
afx_msg type OnSize(...);
これらは交換可能に使用されているようですが、どちらを使用すべきか、または他の要因に依存していますか?
解決
メッセージハンドラーをクラスに追加するには、両方の部分が必要です。メッセージマップは、メッセージハンドラー関数( OnSize
など)の宣言とともに、クラス内で宣言する必要があります。
class CClassWnd : public CBaseClassWnd {
...
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP
};
afx_msg
は単なる空のプレースホルダーマクロです。実際には何も行いませんが、常に慣例により含まれています。
メッセージマップは、クラスの.cppファイルで定義されます。
BEGIN_MESSAGE_MAP(CClassWnd, CBaseClassWnd)
ON_WM_SIZE()
END_MESSAGE_MAP()
これらのマクロは、ウィンドウが受信したメッセージを対応するハンドラー関数にディスパッチできるクラスのルックアップテーブルを生成します。 ON_WM_SIZE
マクロを使用すると、 WM_SIZE
メッセージ内の wParam
および lParam
メッセージパラメータをより意味のある値にデコードできます。メッセージハンドラー関数(この場合は nType
、 cx
、および cy
)。 MFCは、ほとんどのウィンドウメッセージ( WM_LBUTTONDOWN
、 WM_DESTROY
など)にマクロを提供します。
MFCでのメッセージマップの機能の詳細については、こちら MSDNで。
他のヒント
afx_msgは空のマクロです。基本的には、メソッドが読みやすくするためのMFCメッセージハンドラーであることを示すためにあります。 afx_msgがある場合でも、メッセージマップにエントリが必要です。
一部のWindowsメッセージは既に MFC によって処理されているため、これらの場合、派生クラスにメソッドを追加するだけで済みます。
たとえば、 CWnd クラス(他の多くのMFCクラスと同様)は、いくつかのWindowsメッセージをそのメッセージマップに既にマップしています(つまり、 ON_WM_DRAWITEM 、 ON_WM_MEASUREITEM 、 ON_WM_ENTERIDLE など)。
ただし、MFCによってまだマップされていない他のメッセージには、クラスマップとメッセージマップ内のエントリの両方が必要です。