复习总结《一》MFC消息映射
发布日期:2021-06-30 12:12:19 浏览次数:3 分类:技术文章

本文共 3466 字,大约阅读时间需要 11 分钟。

长时间人容易遗忘,从新捡起!特做下记录

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

 

 

 

 

 

转载地址:https://jadeshu.blog.csdn.net/article/details/71496977 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:总结《二》MFC中WinMain和CALLBACK
下一篇:子窗口与父窗口之间消息

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月30日 08时24分42秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章