WinX教程之我的实战(三)
来源:互联网 发布:北京音像大厦 知乎 编辑:程序博客网 时间:2024/05/18 03:03
今天我们来看看第三套教程实例——step003-command。WinX是越来越有意思了,通过这套实例,我们就已经可以处理命令消息。
命令消息
如果你用过MFC,那么你一定知道什么叫命令消息。说的通俗点,命令消息就是和控件、菜单相关的消息,一般命令消息都会和一个ID相关,即控件ID或者菜单的一个条目的ID,也由ID区分不同的命令消息。
实例中用到的命令消息处理宏
在实例CmdDisp中用到了:
l WINX_CMDS_BEGIN
l WINX_CMD
l WINX_CMDS_END
用法是在类定义中,如这样写:
WINX_CMD(IDC_TODO, OnCmdTodo);
WINX_CMD(ID_HELP_ABOUT, OnCmdAbout);
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_UPDATEUI(IDC_ALL, UPDUI_MENUPOPUP)
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原型如下:
BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE);
前一个用于具有第三种状态(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、
public winx::ModalDialog<CHelloDlg, IDD_HELLO>,
public winx::UpdateUI<CHelloDlg>
当我们需要进行命令状态维护时,我们的类(窗口,对话框),需要添加另一个基类winx::UpdateUI<CHelloDlg>。
2、
{
winx::PopupMenu(hWnd, pos.x, pos.y, IDR_MAINMENU);
return TRUE;
}
在实战一中我们已经介绍过拦截系统消息时,只需定义相应函数就可以,不用写消息拦截代码。这里OnContextMenu就是处理系统消息WM_CONTEXTMENU的函数,即当右键单击对话框时。这里的操作是调用WinX内置函数PopupMenu,指定相应菜单资源ID,弹出菜单。
3、
dlg.DoModal(hWnd, IDD_ABOUT);
当我们只是需要一个简单对话框,即我们不需要拦截任何消息,只需要将相应的控件放好(资源文件,对话框设计器),直接像这里调用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,如下,
public winx::ModalDialog< CMyExample3Dlg, IDD_MYEXAMPLE3>,
public winx::UpdateUI< CMyExample3Dlg >
{
};
这里的IDD_MYEXAMPLE3就是我们刚才创建的对话框的资源ID。
步骤六:添加其他资源,如菜单、按钮、静态文本框等,结果如下,
步骤七:添加代码。
将窗口背景设置为白色,代码为:
WINX_BKGND_BRUSH(WHITE_BRUSH);
将窗口上所有控件的背景设置为透明,代码为:
WINX_CTLBKGND_NULL_ALL();
设置右键菜单,代码为:
{
winx::PopupMenu(hWnd, pos.x, pos.y, IDR_MENU1_);
return TRUE;
}
拦截命令消息,并维护命令状态,代码如下:
WINX_CMD(IDM_ABOUTAPP, OnAboutApp);
WINX_CMD(IDM_ITEM1, OnItem1);
WINX_CMD(IDM_ITEM2, OnItem2);
WINX_CMD(IDM_UNCHECKALL, OnUnCheckAll);
WINX_CMDS_END();
WINX_UPDATEUI_BEGIN()
WINX_UPDATEUI(IDM_ITEM1, UPDUI_MENUPOPUP)
WINX_UPDATEUI(IDM_ITEM2, UPDUI_MENUPOPUP)
WINX_UPDATEUI_END();
public:
VOID OnAboutApp(HWND hWnd)
{
winx::SimpleDialog dlg;
dlg.DoModal(hWnd, IDD_ABOUTAPP);
}
VOID OnItem1(HWND hWnd)
{
UISetCheck(IDM_ITEM1, TRUE);
}
VOID OnItem2(HWND hWnd)
{
UISetCheck (IDM_ITEM2, TRUE);
}
VOID OnUnCheckAll(HWND hWnd)
{
UISetCheck (IDM_ITEM1, FALSE);
UISetCheck (IDM_ITEM2, FALSE);
}
步骤八:添加主程序代码,如下:
dlg.DoModal();
运行结果:
注意: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的宏允许带不带;均可。
END AGAIN
- WinX教程之我的实战(三)
- 推荐:《WinX教程之我的实战》
- WinX教程之我的实战(序)
- WinX教程之我的实战(一)
- WinX教程之我的实战(二)
- WinX教程之我的实战(四)
- WinX教程之我的实战(五)
- WinX教程之我的实战(六)
- WinX教程之我的实战(七)
- WinX教程之我的实战(八)
- WinX教程之我的实战系列之序、一、二、三、四、五、六
- WinX教程实战系列
- iOS开发mock接口数据(三)之实战教程
- Vmware vSphere 5.0实战教程之三 Vsphere DRS实战
- Vmware vSphere 5.0实战教程之三 Vsphere DRS实战
- Vmware vSphere 5.0实战教程之三 Vsphere DRS实战
- RabbitMQ 实战教程(三) 发布/订阅
- 【swift3实战】2048 教程(三)
- firefox更新后不能打开加密网页的解决办法
- 如果客户端禁用cookie,那asp.net的form验证程序还能正常运行吗
- Unable to find a javac compiler
- 全国养老金亏空8000亿 引发“延迟退休”呼声。
- javax.servlet.ServletException: [Ljava.lang.Object;
- WinX教程之我的实战(三)
- (爆笑)一名机关工作人员在论坛上发贴:
- 支持联众爱笔畅
- 第二天下午:系统的雏形
- 关于GoogleCodeSearch和正则语法(regexp)(一)正则语法基础
- 利用模式窗口:实现子、父窗体的相互传值
- 几个好用的JS函数
- struts
- UML建模之新思想