A005 MFC从零开始【MFC消息映射机制】

3.MFC消息映射机制

类内必须添加声明宏

DECLARE_MESSAGE_MAP()

类外必须添加实现宏

BEGIN_MESSAGE_MAP(theClass,baseClass)

END_MESSAGE_MAP()

具体实现

class CMyFrameWnd : public CFrameWnd {
	DECLARE_MESSAGE_MAP();
public:
	LRESULT MyOnCreate(WPARAM wParam,LPARAM lParam);
};

BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_MESSAGE(WM_CREATE, MyOnCreate)
END_MESSAGE_MAP()

LRESULT CMyFrameWnd::MyOnCreate(WPARAM wParam, LPARAM lParam) {
	AfxMessageBox(TEXT("WM_Create"));
	return 0;
}

在这里插入图片描述

3.1宏展开

#define DECLARE_MESSAGE_MAP() \
protected: \
	static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
	const AFX_MSGMAP* GetMessageMap() const override; \
	
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
	PTM_WARNING_DISABLE \
	const AFX_MSGMAP* theClass::GetMessageMap() const \
		{ return GetThisMessageMap(); } \
	const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
	{ \
		typedef theClass ThisClass;						   \
		typedef baseClass TheBaseClass;					   \
		__pragma(warning(push))							   \
		__pragma(warning(disable: 4640)) /* message maps can only be called by single threaded message pump */ \
		static const AFX_MSGMAP_ENTRY _messageEntries[] =  \
		{
            
#define ON_MESSAGE(message, memberFxn) \
	{ message, 0, 0, 0, AfxSig_lwl, \
		(AFX_PMSG)(AFX_PMSGW) \
		(static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > \
		(memberFxn)) },
            
            
#define END_MESSAGE_MAP() \
		{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
	}; \
		__pragma(warning(pop))	\
		static const AFX_MSGMAP messageMap = \
		{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
		return &messageMap; \
	}								  \
	PTM_WARNING_RESTORE

简单整理一下

protected: 
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); 
const AFX_MSGMAP* GetMessageMap() const override; 

const AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const {
    return GetThisMessageMap(); 
} 

const AFX_MSGMAP* PASCAL CMyFrameWnd::GetThisMessageMap() 
{ 				   
    static const AFX_MSGMAP_ENTRY _messageEntries[] =  
    {  
        {WM_CREATE, 0, 0, 0, AfxSig_lwl, (AFX_PMSG)(AFX_PMSGW) 
        (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) >(&MyOnCreate))},
        
        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0} 
    }; 

    static const AFX_MSGMAP messageMap = { &CFrameWnd::GetThisMessageMap, &_messageEntries[0] }; 
    return &messageMap; 
}								  

找到其中两个结构体

struct AFX_MSGMAP_ENTRY
{
UINT nMessage; //消息标志
UINT nCode;      //控制代码或WM_NOTIFY通知码
UINT nID;          //控件ID,如果是窗口消息,其值为0
UINT nLastID;    //一定范围命令的最后一个命令或控件ID,用于支持组消息映射
UINT_PTR nSig; //消息处理成员函数的签名代码
AFX_PMSG pfn;  //消息处理函数
};
static const AFX_MSGMAP messageMap = {
   &CFrameWnd::GetThisMessageMap, 
   &_messageEntries[0] 
}; 

在这里插入图片描述

GetThisMessageMap() 静态函数

作用 : 定义静态变量和静态数组,并返回本类静态变量地址( 获取链表头)

messageEntries静态数组

作用: 数组每个元素,保存的为 消息ID 和 处理消息的函数名( 地址 )

messageMap静态变量

作用: 第一个成员,保存父类宏展开的静态变量地址( 负责连接链表 第二个成员,保存本类的静态数组首地址)

GetMessageMap()虚函数

作用 : 返回本类静态变量地址( 获取链表头)

3.2 消息映射宏

消息映射声明和分界宏

名称说明
DECLARE_MESSAGE_MAP声明将在类中使用消息映射来将消息映射到函数(必须在类声明中使用)。
BEGIN_MESSAGE_MAP开始消息映射的定义(必须在类实现中使用)。
BEGIN_TEMPLATE_MESSAGE_MAP开始在包含单个模板参数的类类型上定义消息映射。
END_MESSAGE_MAP结束消息映射的定义(必须在类实现中使用)。

消息映射宏

名称说明
ON_COMMAND指示哪个函数将处理指定的命令消息。
ON_COMMAND_EX指示哪个函数将处理指定的命令消息。
ON_CONTROL指示哪个函数将处理指定的控件通知消息。
ON_MESSAGE指示哪个函数将处理用户定义的消息。
ON_OLECMD指示哪个函数将处理 DocObject 或其容器中的菜单命令。
ON_REGISTERED_MESSAGE指示哪个函数将处理已注册的用户定义消息。
ON_REGISTERED_THREAD_MESSAGE指示哪个函数将在您具有 CWinThread 类时处理已注册的用户定义消息。
ON_THREAD_MESSAGE指示哪个函数将在您具有 CWinThread 类时处理用户定义的消息。
ON_UPDATE_COMMAND_UI指示哪个函数将处理指定的用户界面更新命令消息。

消息映射范围宏

名称说明
ON_COMMAND_RANGE指示哪个函数将处理在宏的前两个参数中指定的命令 ID 的范围。
ON_UPDATE_COMMAND_UI_RANGE指示哪个更新处理程序将处理在宏的前两个参数中指定的命令 ID 的范围。
ON_CONTROL_RANGE指示哪个函数将处理来自在宏的第二个和第三个参数中指定的控件 ID 的范围的通知。 第一个参数是控件通知消息,如 BN_CLICKED

3.3 WM_ 消息的处理程序

以下主题与映射条目相对应。

主题映射条目
A - CON_WM_ACTIVATE 至 ON_WM_CTLCOLOR
D - EON_WM_DEADCHAR 至 ON_WM_ERASEBKGND
F - KON_WM_FONTCHANGE 至 ON_WM_KILLFOCUS
L - MON_WM_LBUTTONDBLCLK 至 ON_WM_MOVING
N - OON_WM_NCACTIVATE 至 ON_WM_NCRBUTTONUP
P - RON_WM_PAINT 至 ON_WM_RENDERFORMAT
SON_WM_SETCURSOR 至 ON_WM_SYSKEYUP
T - ZON_WM_TIMECHANGE 至 ON_WM_WININICHANGE

3.4 用户定义的处理程序

下面的映射条目对应于函数原型。

映射条目函数原型
ON_MESSAGE( , )afx_msg LRESULT memberFxn( WPARAM, LPARAM );
ON_REGISTERED_MESSAGE( , )afx_msg LRESULT memberFxn( WPARAM, LPARAM );
ON_THREAD_MESSAGE( , )afx_msg void memberFxn( WPARAM, LPARAM );
ON_REGISTERED_THREAD_MESSAGE( , )afx_msg void memberFxn( WPARAM, LPARAM );
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值