1、概述
Windows程序靠消息的流动来维持生命,Win32程序在窗口函数中通过庞大的switch/case语句来进行消息比对。为了将庞大的switch/case比对动作简化,也为了使程序更加模块化,windows提供了消息映射机制,通过消息映射表将消息与其处理函数关联起来,并将基类的消息与派生类的消息串接起来,使消息能够按照一定的次序进行比对。
2、消息映射的实现
(1)、几种结构:
enum AfxSig { AfxSig_end =0, AfxSig_vv, }; struct AFX_MSGMAP { AFX_MSGMAP* pBaseMessageMap; AFX_MSGMAP_ENTRY* lpEntries; }; typedef void (CCmdTarget::*AFX_PMSG)(void); struct AFX_MSGMAP_ENTRY { UINT nMessage; UINT nCode; UINT nID; UINT nLastID; UINT nSig; AFX_PMSG pfn; };
(2)、DECLARE_MESSAGE_MAP()、BEGIN_MESSAGE_MAP()、ON_COMMAND()、END_MESSAGE_MAP()宏
#define DECLARE_MESSAGE_MAP() \ static AFX_MSGMAP_ENTRY _messageEntries[]; \ static AFX_MSGMAP messageMap; \ virtual AFX_MSGMAP* GetMessageMap() const; //--------------------------------------------- //BEGIN_MESSAGE_MAP //BEGIN_MESSAGE_MAP(theClass, baseClass) // // AFX_MSGMAP* theClass::GetMessageMap() const // { // return &theClass::messageMap; // } // AFX_MESSAGE theClass::messageMap = // { // &(baseClass::messageMap), // AFX_MSGMAP_ENTRY theClass::_messageEntries[] = // { #define BEGIN_MESSAGE_MAP(theClass, baseClass) \ AFX_MSGMAP* theClass::GetMessageMap() const \ {return &theClass::messageMap;} \ AFX_MSGMAP theClass::messageMap = { \ &(baseClass::messageMap), \ (AFX_MSGMAP_ENTRY*)&(theClass::_messageEntries)}; \ AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \ { //--------------------------------------------------------- //ON_COMMAND(id, memnerFxn) // {WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMAG)memberFxn}, #define ON_COMMAND(id, memberFxn) \ {WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)memberFxn}, //---------------------------------------------------------- //END_MESSAGE_MAP() // {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } // } #define END_MESSAGE_MAP() \ {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \ };
DECLARE_MESSAGE_MAP()宏,在类中声明了静态变量messageMap和_messageEntries,声明了虚函数GetMessageMap。
BEGIN_MESSAGE_MAP、ON_COMMAND、END_MESSAGE_MAP实现上述声明,其中BEGIN_MESSAGE_MAP宏实现了虚函数GetMessageMap、填充了messageMap结构;ON_COMMAND宏填充_messageEntries数组,这个数组给出了消息ID和处理函数之间的对应关系。END_MESSAGE_MAP宏处理结尾工作。
3、MessageMap的消息流动图
注:消息这样的流向是由BEGIN_MESSAGE_MAP(theclass, BaseClass)串接的。