MFC中构建消息映射表的宏位于Include目录下的AFXWIN.H中: #ifdef _AFXDLL #define BEGIN_MESSAGE_MAP(theClass, baseClass) / const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() / { return &baseClass::messageMap; } / const AFX_MSGMAP* theClass::GetMessageMap() const / { return &theClass::messageMap; } / AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = / { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; / AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = / { /
#else #define BEGIN_MESSAGE_MAP(theClass, baseClass) / const AFX_MSGMAP* theClass::GetMessageMap() const / { return &theClass::messageMap; } / AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = / { &baseClass::messageMap, &theClass::_messageEntries[0] }; / AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = / { /
#endif
#define END_MESSAGE_MAP() / {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } / }; / 和AFXMSG.H中: #define ON_COMMAND(id, memberFxn) / { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)&memberFxn },
我第一次看到这个宏时,以为是宏的嵌套定义,在我印象当中没有说宏可以嵌套定义啊,只看到过这种情况: #define PI 3.1415926 #define R 2.0 #define S PI*R*R 这不算嵌套定义吧,让我们来想想宏的本质是什么,就是单纯的代码替换嘛 BEGIN_MESSAGE_MAP(CView,CWnd)就相当于: const AFX_MSGMAP* CView::GetMessageMap() const { return &CView::messageMap; } AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CView::messageMap = { &CWnd::messageMap, &CView::_messageEntries[0] }; AFX_COMDAT const AFX_MSGMAP_ENTRY CView::_messageEntries[] = { 注:#ifdef _AFXDLL用来判断是静态链接MFC库还是动态链接MFC库
ON_COMMAND(CViewid,0)就相当于: { WM_COMMAND, CN_COMMAND, (WORD)CViewid, (WORD)CViewid, AfxSig_vv, 0 },
END_MESSAGE_MAP()就相当于: {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };
把上面三部分组合起来: const AFX_MSGMAP* CView::GetMessageMap() const { return &CView::messageMap; } AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CView::messageMap = { &CWnd::messageMap, &CView::_messageEntries[0] }; AFX_COMDAT const AFX_MSGMAP_ENTRY CView::_messageEntries[] = { { WM_COMMAND, CN_COMMAND, (WORD)CViewid, (WORD)CViewid, AfxSig_vv, 0 }, {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };
看来一个简单的宏也有很多技巧,MFC真是把宏用的出神入化!需要说明的是,宏并不是万能的,他不能提供类型检查,仅仅是简单的代码替换,使用时要小心,而且不宜定义太长的宏,因为使用一次替换一次,会使代码越来越长。