扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
命令消息
如果你用过MFC,那么你一定知道什么叫命令消息。说的通俗点,命令消息就是和控件、菜单相关的消息,一般命令消息都会和一个ID相关,即控件ID或者菜单的一个条目的ID,也由ID区分不同的命令消息。
实例中用到的命令消息处理宏
在实例CmdDisp中用到了:
l WINX_CMDS_BEGIN
l WINX_CMD
l WINX_CMDS_END
用法是在类定义中,如这样写:
宏WINX_CMD带有两个参数,前一个是控件ID,后一个是拦截此命令消息的函数。当该控件被单击时,就调用后一个函数。
我们在定义消息处理函数名前用到了winx_msg宏,winx_msg宏的定义如下:
宏winx_call的定义如下:
__fastcall是另一种不同于__cdecl和__stdcall的函数调用规范,它速度快,使用寄存器来传递参数。要知道详细信息,可以网上搜索。不过我们不用关心它,我们只要在定义消息处理函数名前加上winx_msg宏就可以了。(注:WinX并不依赖于__fastcall,意思就是说,不写调用方式也可以)
在实例CmdState中用到了:
l WINX_CMDS_BEGIN
l WINX_CMD
l WINX_CMDS_END
l WINX_UPDATEUI_BEGIN
l WINX_UPDATEUI
l WINX_UPDATEUI_END
比第一个实例多了后面三个宏。用法就是在类定义中,如下这样写:
引自WinX附带文件WinxPreview.ppt:
l “WTL的命令状态维护机制不错,但是ModalDialog不完全支持该机制。主要的问题在于没有OnIdle消息。”
l “WINX的UpdateUI基于WTL的命令状态维护机制实现,并作出改进。”
这一套消息用来维护命令状态,比如菜单某个条目状态(比如enable状态)改变了,可以自动更新。宏WINX_UPDATEUI带有两个参数,前一个是要维护命令状态的控件ID,后一个是界面元素类型。比如实例CmdState中,我们要更新的是菜单中的命令状态,那后一个参数就应该是UPDUI_MENUPOPUP。
下面中列出了另外一些你可能会用到的界面元素类型:
界面元素类型 |
描述 |
UPDUI_MENUPOPUP, |
菜单 |
UPDUI_MENUBAR |
菜单条 |
UPDUI_CHILDWINDOW |
子窗口 |
UPDUI_TOOLBAR |
工具条 |
UPDUI_STATUSBAR |
状态条 |
除此外,下面列出了一些命令状态及其设置/清楚状态的函数名:
状态 |
描述 |
设置/清楚函数 |
UPDUI_ENABLED |
激活 |
UIEnable |
UPDUI_DISABLED |
反激活 | |
UPDUI_CHECKED |
复选框 |
UISetCheck |
UPDUI_CHECKED2 |
有三种状态 | |
UPDUI_RADIO |
单选框 |
UISetRadio |
UPDUI_TEXT |
文本 |
UISetText |
UPDUI_DEFAULT |
默认按钮(对话框) |
UISetDefault |
UIEnable原型如下:
UISetCheck原型如下:
前一个用于具有第三种状态(UPDUI_CHECKED2)的复选框,这时要求CheckBox要候BS_3STATE或BS_AUTO3STATE。
UISetRadio原型如下:
UISetText原型如下:
UISetDefault原型如下:
其他WinX命令消息处理宏
WINX_CMDS_BEGIN_EX
WINX_CMD_EX
WINX_CMDS_END_EX
与WINX_CMDS_BEGIN/END的区别是,如果消息自身没有处理,会发给活动的子视图处理。
其他问题
在实例CmdState中,还有三个地方需要提一下:
1、
当我们需要进行命令状态维护时,我们的类(窗口,对话框),需要添加另一个基类winx::UpdateUI<CHelloDlg>。
2、
在实战一中我们已经介绍过拦截系统消息时,只需定义相应函数就可以,不用写消息拦截代码。这里OnContextMenu就是处理系统消息WM_CONTEXTMENU的函数,即当右键单击对话框时。这里的操作是调用WinX内置函数PopupMenu,指定相应菜单资源ID,弹出菜单。
3、
当我们只是需要一个简单对话框,即我们不需要拦截任何消息,只需要将相应的控件放好(资源文件,对话框设计器),直接像这里调用DoModal就可以了。一个区别是,这里的对话框资源ID是在DoModal函数中指定的,而非自己定义对话框时在模板参数中指定。
我们不妨实战一下
我们做一个简单的例子,利用一下我们学习前几个教程实例的成果。
功能:
1、 设定背景色为白色;
2、 设定窗口上所有控件背景色为透明;
3、 具有菜单和命令状态维护功能,用Check;
4、 弹出右键菜单。
假设我们的项目名为Example3。
步骤一:打开VC 6.0 英文版,:p;
步骤二:利用Wizard创建Win32 Application,选择“A Simple Win32 Application”;
步骤三:添加资源文件,如下图,
步骤四:添加对话框,Insert即可,如下图:
(请高手们保持耐心,:))
之后选择对话框类别,New即可,生成对话框资源后,将对话框资源ID修改为IDD_MYEXAMPLE3。其他按钮控件我们一会再加。
步骤五:定义主窗口类(直接在主程序文件Example3.cpp定义中即可),我们的主窗口类是一个模式对话框,而且我们要做命令状态维护,所以别忘了要多加一个基类winx::UpdateUI,如下,
这里的IDD_MYEXAMPLE3就是我们刚才创建的对话框的资源ID。
步骤六:添加其他资源,如菜单、按钮、静态文本框等,结果如下,
步骤七:添加代码。
将窗口背景设置为白色,代码为:
WINX_BKGND_BRUSH(WHITE_BRUSH);
将窗口上所有控件的背景设置为透明,代码为:
WINX_CTLBKGND_NULL_ALL();
设置右键菜单,代码为:
拦截命令消息,并维护命令状态,代码如下:
步骤八:添加主程序代码,如下:
运行结果:
注意:1、不知大家注意没有,每个WINX_CMDS_xx宏后面都有分号,而并非每个WINX_UPDATEUI_xx宏有,只有最后一个WINX_UPDATEUI_END();有。2、对话框的主菜通过在资源中直接设定。
不知大家在上面运行结果图中发现什么问题没有?有奖问答!J
END
关于上面提到的分号“;”问题,咨询xushiwei后补充如下:
winx旧的习惯是所有的宏后加上;(如上面的WINX_CMD),而wtl的习惯是不带;(如上面的WINX_UPDATEUI是依赖wtl实现的), 这就就出现了不一致的情况。目前winx没有消除这种不一致。考虑到可能给用户造成困惑,winx决定在下一个release全部统一为不带;号。不过我们会兼容目前的文法,也就是说,winx的宏允许带不带;均可。
查看本文来源
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者