WM_COMMAND与消息的传递


上面是一张MFC的类图局部。

MFC将消息分为三大类:

①    命令消息WM_COMMAND:凡是由CCmdTarget派生的类,均可接收该消息。

②    标准消息WM_xxx:凡是由CWnd派生的类,均可接收该消息。

③    控件通知消息WM_NOTIFY/WM_COMMAND:由控件产生,为的是向其父窗口发送通知。Windows9x及以上控件传送的是WM_NOTIFY,而老版本控件为了兼容,依然传送WM_COMMAND

注意:WM_NOTIFY其实就是WM_COMMANDWM_NOTIFY是为了将控件发送给父窗口的WM_COMMAND与其他WM_COMMAND区分,才使用了这样一个写法。但在实际中依然是使用WM_COMMAND来传送WM_NOTIFY

由以上可知:

①    CCmdTarget派生的类一定可以接收WM_COMMAND

②    CWnd派生的类一定可以接收WM_COMMANDWM_xxx,当然也包括WM_NOTIFY。故而CWnd派生的类一定可以接收任何Windows消息。

③    由CCmdTarget派生但不由CWnd派生的类(如CWinAppCDoucument等),均不可以接收WM_xxx,只可以接收WM_COMMAND(以及WM_NOTIFY)。

 

会产生WM_COMMAND的,一定就是UI对象,如菜单和按钮等。对每一个WM_COMMAND,必须有一个对应的处理函数,将消息与处理函数绑定在一起,称之为Command Binding。

对于所对应的处理函数,若是标准的Windows消息,则不需要我们指定处理函数的名称,每个标准Windows消息都有自己的默认处理函数名称。如WM_LBUTTONDOWN所对应的处理函数名称为OnLButtonDown。

  

理论上来说,所有派生自的CCmdTarget类都应该具有DECLARE_MESSAGE_MAPBEGIN_MESSAGE_MAPEND_MESSAGE_MAP宏,这样才能使得该派生类具备接收消息并上溯的能力。但是,实际上,并非所有派生类都有这三个宏。CWinThread就是没有这三个宏的。

CWinThread没有这三个宏,就导致它无法接收消息,也无法上溯。那它的派生类该怎么办?岂不是无法上溯?实际上,这里使用了一个技巧。CCmdTarget->CWinThread->CWinApp。对于CWinApp,虽然它的父类CWinThread没有这三个宏,但这不妨碍CWinApp带有这三个宏。CWinApp带有这三个宏,那它就具备接收消息并上溯的能力。可是CWinApp是无法上溯到父类CWinThread,因为父类没有这三个宏。于是,在CWinAppBEGIN_MESSAGE_MAP宏的参数里,是这样写的:

BEGIN_MESSAGE_MAP(CWinApp,CCmdTarget)

CWinApp的消息基类没有写成是父类CWinThread,而是写成了祖父类CCmdTarget。当有消息从CWinApp上溯时,会直接根据这里的参数直达祖父类CCmdTarget

消息传递时,产生了跳跃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值