今天我们来看看第三套教程实例——step003-command。WinX是越来越有意思了,通过这套实例,我们就已经可以处理命令消息。

命令消息

如果你用过MFC,那么你一定知道什么叫命令消息。说的通俗点,命令消息就是和控件、菜单相关的消息,一般命令消息都会和一个ID相关,即控件ID或者菜单的一个条目的ID,也由ID区分不同的命令消息。

实例中用到的命令消息处理宏

在实例CmdDisp中用到了:

l         WINX_CMDS_BEGIN

l         WINX_CMD

l         WINX_CMDS_END

用法是在类定义中,如这样写:

WINX_CMDS_BEGIN();
    WINX_CMD(IDC_TODO, OnCmdTodo);
    WINX_CMD(ID_HELP_ABOUT, OnCmdAbout);
WINX_CMDS_END();

宏WINX_CMD带有两个参数,前一个是控件ID,后一个是拦截此命令消息的函数。当该控件被单击时,就调用后一个函数。

我们在定义消息处理函数名前用到了winx_msg宏,winx_msg宏的定义如下:

#define winx_msg    winx_call

宏winx_call的定义如下:

#define winx_call   __fastcall

__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_BEGIN()

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原型如下:

BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE);

UISetCheck原型如下:

BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE);
BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE);

前一个用于具有第三种状态(UPDUI_CHECKED2)的复选框,这时要求CheckBox要候BS_3STATE或BS_AUTO3STATE。

UISetRadio原型如下:

BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE);

UISetText原型如下:

BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE);

UISetDefault原型如下:

BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE);

其他WinX命令消息处理宏

WINX_CMDS_BEGIN_EX

WINX_CMD_EX

WINX_CMDS_END_EX

与WINX_CMDS_BEGIN/END的区别是,如果消息自身没有处理,会发给活动的子视图处理。

其他问题

在实例CmdState中,还有三个地方需要提一下:

1、

class CHelloDlg : 

       public winx::ModalDialog<CHelloDlg, IDD_HELLO>,

       public winx::UpdateUI<CHelloDlg>

当我们需要进行命令状态维护时,我们的类(窗口,对话框),需要添加另一个基类winx::UpdateUI<CHelloDlg>。

2、

BOOL OnContextMenu(HWND hWnd, winx::CPoint pos)
{
       winx::PopupMenu(hWnd, pos.x, pos.y, IDR_MAINMENU);

return TRUE;
}

在实战一中我们已经介绍过拦截系统消息时,只需定义相应函数就可以,不用写消息拦截代码。这里OnContextMenu就是处理系统消息WM_CONTEXTMENU的函数,即当右键单击对话框时。这里的操作是调用WinX内置函数PopupMenu,指定相应菜单资源ID,弹出菜单。

3、

winx::SimpleDialog dlg;

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,如下,

class CMyExample3Dlg : 
       public winx::ModalDialog< CMyExample3Dlg, IDD_MYEXAMPLE3>,
       public winx::UpdateUI< CMyExample3Dlg >

{

};

这里的IDD_MYEXAMPLE3就是我们刚才创建的对话框的资源ID。

步骤六:添加其他资源,如菜单、按钮、静态文本框等,结果如下,

步骤七:添加代码。

将窗口背景设置为白色,代码为:

WINX_BKGND_BRUSH(WHITE_BRUSH);

将窗口上所有控件的背景设置为透明,代码为:

WINX_CTLBKGND_NULL_ALL();

设置右键菜单,代码为:

BOOL OnContextMenu(HWND hWnd, winx::CPoint pos)
{
       winx::PopupMenu(hWnd, pos.x, pos.y, IDR_MENU1_);

return TRUE;

}

拦截命令消息,并维护命令状态,代码如下:

WINX_CMDS_BEGIN();
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);
    }

步骤八:添加主程序代码,如下:

CMyExample3Dlg dlg;
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教程之我的实战(三)相关推荐

  1. Docker最全教程——从理论到实战(三)

    容器是应用走向云端之后必然的发展趋势,因此笔者非常乐于和大家分享我们这段时间对容器的理解.心得和实践. 本篇教程持续编写了2个星期左右,只是为了大家更好地了解.理解和消化这个技术,能够搭上这波车. 你 ...

  2. Docker最全教程——从理论到实战(六)

    Docker最全教程--从理论到实战(六) 原文:Docker最全教程--从理论到实战(六) 托管到腾讯云容器服务 托管到腾讯云容器服务,我们的公众号"magiccodes"已经发 ...

  3. Docker最全教程——从理论到实战(一)

    Docker最全教程--从理论到实战(一) 目录 前言 随着生产力的发展尤其是弹性架构的广泛应用(比如微服务),许多一流开发者都将应用托管到了应用容器上,比如Google.微软.亚马逊.腾讯.阿里.京 ...

  4. 里面使用轮播_小程序ColorUI框架初步使用教程及个人项目实战

    小程序ColorUI框架初步使用教程及个人项目实战 最近在写自己的一个微信小程序项目<阿涛技术博客>,目前还在写前端小程序部分,之前我有用过小Weiui,Linui等微信小程序UI框架,在 ...

  5. 【Qt】数据库实战(三)

    00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 增删改查操作 04. 名字绑定和位置绑定 05. 程序示例 06. 批处理操作 07. 事务操作 08. 附录 01. 概 ...

  6. Docker最全教程——从理论到实战(七)

    Docker最全教程--从理论到实战(七) 原文:Docker最全教程--从理论到实战(七) 在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解 ...

  7. Docker最全教程——从理论到实战(九)

    在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解知识点而进行讲解.也就是说,笔者希望能够让大家将理论.知识.思想和指导应用到工作的实际场景和实 ...

  8. Docker最全教程——从理论到实战(八)

    在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解知识点而进行讲解.也就是说,笔者希望能够让大家将理论.知识.思想和指导应用到工作的实际场景和实 ...

  9. Docker最全教程——从理论到实战(五)

    在笔者参加腾讯容器服务技术交流会时,我们了解到了藏区牧民的目前的生活艰辛状况,因此除了在同事朋友之间推荐其土特产之外,我们也在此进行初步分享,希望略尽绵薄之力,能够帮助到他们: 货真价实.确保都是37 ...

最新文章

  1. 655. Print Binary Tree 解题报告(树)
  2. DSP专家给你一个选择FPGA的理由(让人看了热血沸腾的一篇科普文章)
  3. swift_022(Swift 的下标脚本)
  4. iOS时间格式化遇到的坑
  5. java的main函数为什么是public static void main(String[] args)
  6. 老司机的应用级监控——spring?actuator
  7. 为什么使用接口编程{转载}
  8. php请求图片,PHP - 发送GET请求并获取图片作为回报
  9. 谷歌浏览器历史版本下载网址
  10. 偷窥JCache API(JSR 107)
  11. 首字母筛选 java_【Java习作】提取汉字拼音首字母(Java版)
  12. [每日学习3.26/3.27] 游戏研发面经学习 - 阿V
  13. 音频处理相关内容学习——自动编码器——变分自动编码器——频谱图
  14. 基于jsp+mysql+ssm妇女联合会管理系统-计算机毕业设计
  15. npm ERR!无法安装任何包的解决办法
  16. Flink 理解流式计算中的窗口概念
  17. python数据分析师下载_2020云开见明Python数据分析师特训营,全套课程资源下载...
  18. 万能遥控器【解题报告】
  19. openpyxl操作excel
  20. 这是最后一篇:Adobe

热门文章

  1. Vue开发之基础路由
  2. 用echarts实现水滴图效果
  3. 子佩录音盒,winform实现拨打电话,接听电话,显示客户信息,并录音,写入一条记录
  4. 科技初创企业遭遇IPO寒冬
  5. 抖音书单号如何快速上热门
  6. pytorch torchvision.datasets
  7. mc杀人Linux指令,杀人雪球指令详解 教你怎么做杀人雪球
  8. EasyNVR摄像头网页无插件直播H5、谷歌Chrome直播方案中如何降低播放延迟问题
  9. 软件工程专业期末项目开发全流程模拟日志(第一天)
  10. hbase安装配置 整合到hadoop