MFC 命令和消息路由 (command and message route)

MFC 命令和消息路由 <command and message route>
<reference MFC TNO 21>
文档将讨论MFC中WM_COMMAND消息的传送和派发机制,同样会涉及一些Window消息的高级主题
 

1    Command消息
WM_COMMAND消息的产生主要是由菜单项和加速键以及对话框中的按钮被按下产生的
1.1  Command IDs
一般适用”ID_”前缀来指示通用Command ID(command IDs), Command ID 要求 >= 0x8000;
如果在一个程序的STRINGTABLE中包含与Command同样ID的字符串,那么在状态栏(message line)中会显示关于命令消息的描述信息(在STRINGTABLE同ID的字符串);
 

在一个应用程序的资源中一个ID可在以下3种情况下重复出现:
1 STRINGTABLE中重复出现的ID指向一个字符串用于命令功能提示
2 MENU中可以出现多个菜单项使用相同ID号
3 (高级) 对话框中的按钮实现GOSUB Command
 

1.2 GOSUB Command 在对话框中使用命令消息架构(Using Command Architecture in Dialogs)
当前只有ID号大于0x8000的Command才适用于MFC的GOSUB 对话框/命令
名词解释: GOSUB
在一个一般对话框上设置一个一般按钮,且将按钮的ID设为一个合适的Command ID, 这样当按钮按下的时候,对话框的拥有者(一般情况下为MainFrame)通常就会收到Command消息;
 

Command的路由和状态改变机制,在FrameWork中工作的非常良好

对话框也可以从这种机制中受益,而这样要求对控件设定合适的Comamnd ID 但这些都不能自动化完成的 而是需要手工的添加额外的代码

首先必要的条件是 控件的ID必须要要大于0x8000 因为很多Command命令都是从FrameWork里派发到指定的Dialog中 ,所以在一些特定非共享的Dialog中控件的ID默认为小与0x7fff

在Dialog代码中可以调用CWnd::OnUpdateDialogControls()并将MainFrame Window的地址传入,该函数根据MainFrame Window中是否有对应的命令消息响应函数会自动激活或失效一个对话框控件;对于一些Control Bar控件, 这个函数是在应用程序Idle循环中自动的调用的。如果在一般的对话框中实现这种功能,需要由编码者调用这个函数来完成指定的功能。最简单的用法,我们可以实现自动的使一些对话框按钮激活或失效: 
注意:  ON_COMMAND和 ON_BN_CLICKED对于激活一个按钮的作用是相同的

1.3 ON_UPDATE_COMMAND_UI的调用
在程序运行的一直维护菜单或按钮状态会导致很大的开销;一般的维护菜单状态是处理WM_INITMENUPOPUP消息来实现的;
在MFC2.0中的实现同样也是如此,在CMainFrame处理WM_INITMENUPOPUP中通过命令消息路调用ON_UPDATE_COMMAND_UI由来改变菜单项的状态

CMainFrame同样处理WM_ENTERIDLE在状态栏中显示当前选中ToolBar上对应空间的描述信息(前述);

 
 

2   Window消息
2.1 CWnd的问题

CWnd::OnChildNotify消息的实现提供了一个强大的可扩展的架构 使得子窗体(控件)来获取指定消息的处理或发送通知消息(Command消息 控件通知消息)到父窗体中;
如果一个子窗体(控件)是一个CWnd对象,虚函数OnChildNotify会被调用并传送原先的消息(MSG);子窗体可以处理该消息(常见)也可以改变这个消息发送给父窗体(很少);
 

CWnd::OnChildNotify默认的实现,使得OnChildNotify钩取以下消息使得子窗体优先处理:

WM_MEASUREITEM and WM_DRAWITEM (for self-draw)
WM_COMPAREITEM and WM_DELETEITEM (for self-draw)
WM_HSCROLL and WM_VSCROLL
WM_CTLCOLOR
WM_PARENTNOTIFY
可以看出MFC通过这种技术就使得一些需要由父窗体完成的绘制(Owner Draw) 变成了自绘制(Self Draw);

2.2 CFrameWnd的问题
CFrameWnd实现了Command消息的路由和大多数界面元素状态更新
CFrameWnd维护管理激活的视图,以下消息会通过路由派发给激活的视图:
全部的Command消息(活动的视图优先处理)
WM_HSCROLL and WM_VSCROLL 来自于附属的滚动条控件
WM_ACTIVATE (and WM_MDIACTIVATE for MDI) 依次调用 CView::OnActivateView

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值