消息映射
一、消息映射表
AFX_MSGMAP_ENTRY結構表示消息映射表中的一個消息映射項,將消息與處理該消息的成員關聯起來。
struct AFX_MSGMAP_ENTRY { UINT nMessage; //消息標志 UINT nCode; //控制代碼或WM_NOTIFY通知碼 UINT nID; //控件ID,如果是窗口消息,其值為0 UINT nLastID; //一定范圍命令的最后一個命令或控件ID,用于支持組消息映射 UINT_PTR nSig; //消息處理成員函數的簽名代碼 AFX_PMSG pfn; //消息處理函數 };AFX_MSGMAP表示一個消息映射表,包括兩個成員,一個指向基類的消息映射表,一個指向一組消息映射項的指針。
struct AFX_MSGMAP { //指向基類消息映射表的指針 #ifdef _AFXDLLconst AFX_MSGMAP * (PASCAL * pfnGetBaseMap)(); #elseconst AFX_MSGMAP * pBaseMap; #endif //消息映射表的表項,將消息與成員函數關聯起來const AFX_MSGMAP_ENTRY * lpEntries };由此可見,每個類的消息映射表中均包含了父類的消息映射表的信息,因此消息映射表提供了基類成員處理子類消息的能力。
二、在CCmdTarget派生類中添加消息映射表
(1)在聲明類的頭文件中加入DECLARE_MESSAGE_MAP()宏。
#ifdef _AFXDLL #define DECLARE_MESSAGE_MAP() \ private:\static const AFX_MSGMAP_ENTRY _messageEntries[]; //容納消息映射項的靜態數組 protected:\static const AFX_MSGMAP messageMap;\ //消息映射表static const AFX_MSGMAP * PASCAL GetThisMessageMap();\virtual const AFX_MSGMAP * GetMessageMap() const;\ //獲取消息映射表的指針 #else #define DECLARE_MESSAGE_MAP() \ private:\static const AFX_MSGMAP_ENTRY _messageEntries;\ //容納消息映射項的靜態數組 protected:\ static const AFX_MSGMAP messageMap;\ //消息映射表virtual const AFX_MSGMAP * GetMessageMap() const;\ //獲取消息映射表的指針 #endif
(2)在聲明類的實現文件中加入BEGIN_MESSAGE_MAP(theClass,baseClass)宏和END_MESSAGE_MAP宏。
?????? BEGIN_MESSAGE_MAP宏完成三件事:
?????????? a.返回當前類的消息映射表的虛成員。
?????????? b.初始化靜態消息映射表成員。
?????????? c.開始初始化消息映射表項數組
#ifdef _AFXDLL #define BEGIN_MESSAGE_MAP(theClass,baseClass)\ const AFX_MSGMAP * PASCAL theClass::GetThisMessageMap()\ {return &theCalss::messageMap;}\ const AFX_MSGMAP * theClass::GetMessageMap() const\ //返回當前類的消息映射表的虛成員 {return &theClass::messageMap;}\ AFX_COMDAT const AFX_MSGMAP theClass::messageMap = \ //設置基類的消息映射表入口,設置消息映射表的消息映射項數組的入口 {&baseClass::GetThisMessageMap,&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_COMDOT const AFX_MSGMAP theClass::messageMap = \ //設置基類的消息映射表入口,設置消息映射表的消息映射項數組的入口 {&baseClass::messageMap,&theClass::_messageEntries[0]};\ AFX_COMDOT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \ //開始初始化類的靜態消息映射表項數組 {\ #endif?
???????? END_MESSAGE_MAP宏在類的消息映射數組中添加最后一項,以作為數組結束標記。
#define END_MESSAGE_MAP()\{0,0,0,0,AfxSig_end,(AFX_PMSG)0}\ };\For example:
BEGIN_MESSAGE_MAP(CMyView,CView) //...忽略了消息映射宏 END_MESSAGE_MAP三、在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP宏之間加入相應的消息映射宏
MFC中的消息主要分為四種:窗口消息、通知信息、命令消息和反射消息。
(1)CWnd類將窗口消息和其成員函數掛鉤起來,窗口消息又稱標準消息。
#define ON_WM_DESTROY()\ {WM_DESTROY,0,0,0,AfxSig_vv,\ (AFX_PMSG)(AFX_PMSGW)(static_cast<void (AFX_MSG_CALL CWnd::*)>(OnDestroy))},(2)命令消息的消息映射宏如下:(包含兩個參數,一個是表示要處理的命令ID,另一個是處理該命令的成員函數)
ON_COMMAND宏和ON_COMMAND_RANGE宏:不會將命令傳遞給處理鏈的下一個對象。
#define ON_COMMAND(id,memberFxn)\ {WM_COMMAND,CN_COMMAND,(WORD)id,AfxSigCmd_v,\ static_cast<AFX_PMSG>(memberFxn)}, #define ON_COMMAND_RANGE(id,idLast,memberFxn)\ {WM_COMMAND,CN_COMMAND,(WORD)id,(WORD)idLast,AfxSigCmd_RANGE,\ (AFX_PMSG)(static_cast<void (AFX_MSG_CALL CCmdTarget::*)(UINT)>(memberFxn))},ON_COMMAND_EX宏和ON_COMMAND_EX_RANGE宏:返回FALSE允許命令沿著命令處理鏈繼續處理。
#define ON_COMMAND_EX(id,idLast,memberFxn)\ {WM_COMMAND,CN_COMMAND,(WORD)id,(WORD)idLast,AfxSigCmd_EX,\ (AFX_PMSG)(static_cast<BOOL (AFX_MSG_CALL CCmdTarget::*)(UINT)>(memberFxn))},ON_UPDATE_COMMAND_UI宏和ON_UPDATE_COMMAND_UI_RANGE宏:用于更新菜單、控制條命令按鈕的外觀。
#define ON_UPDATE_COMMAND_UI(id,memberFxn)\ {WM_COMMAND,CN_UPDATE_COMMAND_UI,(WORD)id,(WORD)id,AfxSigCmdUI,\ (AFX_MSG)(static_cast<void (AFX_MSG_CALL CCmdTarget::*)(CCmdUI*)>(memberFxn))},(3)通知消息
控件通知消息是控件窗口發送到其父窗口的消息,父窗口的消息映射表通過添加控件通知消息映射宏來處理子控件窗口發來的通知消息。控件通知消息映射宏有ON_CONTROL和ON_CONTROL_RANGE。
#define ON_CONTROL(wNotifyCode,id,memberFxn)\ {WM_COMMAND,(WORD)wNotifyCode,(WORD)id,(WORD)id,AfxSigCmd_v,\ (static_cast<AFX_PMSG>(memberFxn))}, #define ON_CONTROL_RANGE(wNotifyCode,id,idLast,memberFxn)\ {WM_COMMAND,(WORD)wNotifyCode,(WORD)id,(WORD)idLast,AfxSigCmd_RANGE,\ (AFX_PMSG)(static_cast<void (AFX_MSG_CALL CCmdTarget::*)(UINT)>(memberFxn))},通知消息即WM_NOTIFY消息,相應的宏為ON_NOTIFY和ON_NOTIFY_RANGE。
#define ON_NOTIFY(wNotifyCode,id,memberFxn)\ {WM_NOTIFY,(WORD)(int)wNotifyCode,(WORD)id,(WORD)id,AfxSigNotify_v,\ (AF_PMSG)(static_cast<void (AFX_MSG_CALL CCmdTarget::*)(NMHDR*,LRESULT*)>(memberFxn))},(4)反射消息
對子窗口向父窗口發送的通知消息或控件通知,父窗體會將該消息轉化為對應的反射消息發送給子窗體,以優先讓子窗體處理。
反射的通知消息的映射宏ON_NOTIFY_REFLECT,及增強版的ON_NOTIFY_REFLECT_EX宏。
#define ON_NOTIFY_REFLECT(wNotifyCode,memberFxn)\ {WM_NOTIFY+WM_REFLECT_BASE,(WORD)(int)wNotifyCode,0,0,AfxSigNotify_v,\ (AFX_PMSG)(static_cast<void (AFX_MSG_CALL CCmdTarget::*(NMHDR*,LRESULT*))>(memberFxn))},反射的控件通知消息的映射宏ON_CONTROL_REFLECT,及增強版的ON_CONTROL_REFLECT_EX宏。
#define ON_CONTROL_REFLECT\ {WM_COMMAND+WM_REFLECT_BASE,(WORD)wNotifyCode,0,0,AfxSigCmd_v,\ (AFX_PMSG)(static_cast<BOOL (AFX_MSG_CALL CCmdTarget::*)(void)>(memberFxn))},其他反射消息映射宏
ON_WM_CTLCOLOR_REFLECT
ON_WM_DRAWITEM_REFLECT
ON_WM_MEASUREITEM_REFLECT
ON_WM_DELETEITEM_REFLECT
ON_WM_CHARTOITEM_REFLECT
ON_WM_VKEYTOITEM_REFLECT
ON_WM_COMPAREITEM_REFLECT
ON_WM_HSCROLL_REFLECT
ON_WM_VSCROLL_REFLECT
ON_WM_PARENTNOTIFY_REFLECT
不同類別的消息,其消息映射宏是不同的,也具有不同的參數。
轉載于:https://www.cnblogs.com/chengtulang/p/3180951.html
總結
- 上一篇: 设计模式学习之单件模式singleton
- 下一篇: 可爱的玩笑