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真是把宏用的出神入化!需要說明的是,宏並不是萬能的,他不能提供類型檢查,僅僅是簡單的代碼替換,使用時要小心,而且不宜定義太長的宏,因爲使用一次替換一次,會使代碼越來越長。