复习总结《一》MFC消息映射
长时间人容易遗忘,从新捡起!特做下记录
MFC消息映射
1.在MFC中消息映射主要牵扯到三个宏分别为:
DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(theClass, baseClass)
END_MESSAGE_MAP()
2.先看源码
#define DECLARE_MESSAGE_MAP() \
protected: \
	static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
	virtual const AFX_MSGMAP* GetMessageMap() const; \
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
	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; \
	}	
3.上述源码中牵扯到两个结构体分别为
struct AFX_MSGMAP_ENTRY
{
	UINT nMessage;   // windows message
	UINT nCode;      // control code or WM_NOTIFY code
	UINT nID;        // control ID (or 0 for windows messages)
	UINT nLastID;    // used for entries specifying a range of control id's
	UINT_PTR nSig;       // signature type (action) or pointer to message #
	AFX_PMSG pfn;    // routine to call (or special value)
};
struct AFX_MSGMAP
{
	const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
	const AFX_MSGMAP_ENTRY* lpEntries;
};包含两部分:1.函数指针(指向父类的获取AFX_MSGMAP的指针的静态函数) 2.AFX_MSGMAP_ENTRY结构体的指针
形成结构图

4.无论MFC中消息的走向如何(是向基类直接走还是横向走消息),我们先必须把整个爬行路线网建立起来,即如上图就可以把基类和派生类连接起来。
作为消息基类CCmdTarget需要特殊处理,即CCmdTarget的父类的AFX_MSGMAP为NULL,CCmdTarget内的AFX_MSGMAP_ENTRY仅包含一项, 如下:
CCmdTarget类头文件包含
DECLARE_MESSAGE_MAP()CCmdTarget类源文件有
const AFX_MSGMAP* CCmdTarget::GetMessageMap() const
{
	return GetThisMessageMap();
}
const AFX_MSGMAP* CCmdTarget::GetThisMessageMap()
{
	static const AFX_MSGMAP_ENTRY _messageEntries[] =
	{
		{ 0, 0, AfxSig_end, 0 }     // nothing here
	};
	static const AFX_MSGMAP messageMap =
	{
		NULL,
		&_messageEntries[0]
	};
	return &messageMap;	
}
简化版本:
#ifndef __DEFINE_H__
#define __DEFINE_H__
typedef void (*CALL_MSG)(int wParam, int lParam);
struct MSG_MAP_ENTRY
{
    unsigned int nMessage;    //消息类型
    unsigned int nSig;        // 信号类型  
    CALL_MSG pfn;             //回调函数,即处理函数  
};
struct MSG_MAP
{
    MSG_MAP* (*pfnGetBaseMap)();
    MSG_MAP_ENTRY* lpEntries;
};
#define DECLARE_MESSAGE_MAP()                                   \
        static const  MSG_MAP*  GetThisMessageMap();      \
        virtual const  MSG_MAP* GetMessageMap();
#define BEGIN_MESSAGE_MAP(theClass, baseClass)                  \
        const MSG_MAP*  theClass::GetMessageMap(){                \
            return GetThisMessageMap();                         \
        }                                                       \
        const MSG_MAP*  theClass::GetThisMessageMap()            \
        {                                                       \
            typedef theClass ThisClass;                         \
            typedef baseClass TheBaseClass;                     \
            static const MSG_MAP_ENTRY _messageEntries[] =                     \
            {
#define END_MESSAGE_MAP()                                               \
                {0, 0, (CALL_MSG)0 }                  \
            };                                                          \
            static const AFX_MSGMAP messageMap =                        \
            { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] };  \
            return &messageMap;                                         \
        }
#endif
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号