有过MFC编程经验的都了解MFC中的消息封装。巧妙地利用宏定义实现了windows消息和消息处理函数的映射(也可以理解成UINT型命令和handler之间的映射)。通常,我们会在MFC的窗口类头文件中看到一行宏定义代码。
DECLARE_MESSAGE_MAP()
而在窗口类文件中,会看到类似如下的一堆宏定义:
BEGIN_MESSAGE_MAP(DlgTest, CDialogEx)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_BN_CLICKED(IDC_BTN_OK, OnBnClickedBtnOk)
ON_MESSAGE(WM_TEST, OnTestHandler)
END_MESSAGE_MAP()
我们追根溯源,找到这些宏定义的定义处会发现,这些宏定义定义一个窗口类的类static变量和一系列配套的类static函数,这些变量和函数项目配合,封装了MFC的消息映射。
#define DECLARE_MESSAGE_MAP() \
protected: \
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
PTM_WARNING_DISABLE \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return GetThisMessageMap(); } \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass;\
typedef baseClass TheBaseClass;\
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
#define END_MESSAGE_MAP() \
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return &messageMap; \
}\
PTM_WARNING_RESTORE
其中,实现消息映射最关键的是变量#define DECLARE_MESSAGE_MAP() \AFX_MSGMAP_ENTRY _messageEntries,