MFC的消息机制

MFC中所有能够进行消息处理的类都是基于CCmdTarget类的,也就是说CCmdTarget类是所有可以进行消息处理类的父类。 CCmdTarget类是MFC处理命令消息的基础和核心。

在MFC的框架结构下,可以进行消息处理的类的头文件里面都会含有 DECLARE_MESSAGE_MAP()宏,这里主要进行消息映射和消息处理函数的声明。
BEGIN_MESSAGE_MAP(CInheritClass, CBaseClass)
//{{AFX_MSG_MAP(CInheritClass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

同时,MFC定义了下面的两个主要结构:
AFX_MSGMAP_ENTRY
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message (Windows消息的ID号)
UINT nCode; // control code or WM_NOTIFY code (控制消息的通知码)
UINT nID; // control ID (or 0 for windows messages) (Windows控制消息的ID)
UINT nLastID; // used for entries specifying a range of control id's
UINT nSig; // signature type (action) or pointer to message (消息的动作标识)
AFX_PMSG pfn; // routine to call (or special value) (一个指向和该消息相应的执行函数的指针)
};

AFX_MSGMAP:
//AFX_MSGMAP 主要作用是两个:1,用来得到基类的消息映射入口地址。2,得到本身的消息映射入口地址。
struct AFX_MSGMAP
{
#ifdef _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
};

根据以上MFC系统定义的数据结构, MFC把所有的消息一条条填入到AFX_MSGMAP_ENTRY结构中去,形成一个数组,该数组存放了所有的消息和与它们相关的参数。同时通过 AFX_MSGMAP能得到该数组的首地址,同时得到基类的消息映射入口地址,这是为了当本身对该消息不响应的时候,就调用其基类的消息响应。

3。 MFC下消息机制的实现过程:

实际上所有MFC的窗口类都通过钩子函数_AfxCbtFilterHook截获消息,并且在钩子函数 _AfxCbtFilterHook中把窗口过程设定为AfxWndProc。原来的窗口过程保存在成员变量m_pfnSuper中。所以在MFC框架 下,一般一个消息的处理过程是这样的:

(1) 函数AfxWndProc接收Windows操作系统发送的消息。
(2) 函数AfxWndProc调用函数AfxCallWndProc进行消息处理,把对句柄的操作转换成对CWnd对象的操作。
(3) 函数AfxCallWndProc调用CWnd类的方法WindowProc进行消息处理。
(注意AfxWndProc和 AfxCallWndProc都是AFX的API函数。而WindowProc已经是CWnd的一个方法。所以可以注意到在WindowProc中已经没 有关于句柄或者是CWnd的参数了。)
(4) 方法WindowProc调用方法OnWndMsg进行正式的消息处理,即把消息派送到相关的方法中去处理。如果nWndMsg方法没有对消息进行处理的 话,就调用DefWindowProc对消息进行处理。这是实际上是调用原来的窗口过程进行缺省的消息处理。


第(4)步中消息 派送的实现过程:

实际上在CWnd类中都保存了一个AFX_MSGMAP的结构,而在AFX_MSGMAP结构中保存有所有我们用 ClassWizard生成的消息的数组的入口,我们把传给OnWndMsg的message和数组中的所有的message进行比较,找到匹配的那一个 消息。这些由系统通过函数AfxFindMessageEntry来实现。

找到了那个message,实际上我们就得到一个 AFX_MSGMAP_ENTRY结构,而我们在上面已经提到AFX_MSGMAP_ENTRY保存了和该消息相关的所有信息,其中主要的是消息的动作标 识和跟消息相关的执行函数。然后我们就可以根据消息的动作标识调用相关的执行函数,而这个执行函数实际上就是通过ClassWizard在类实现中定义的 一个方法。这样就把消息的处理转化到类中的一个方法的实现上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值