Duilib学习笔记《05》— 消息响应处理

Duilib学习笔记《04》中已经知道了如何将窗体显示出来,而如何处理窗体上的事件、消息呢?


一. 系统消息

窗体显示的时候我们就已经说了,窗体是继承CWindowWnd类的,对于窗体的部分消息的处理,需要重载该类的LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 函数。在显示窗体部分我们创建窗体WM_CREATE消息以及屏蔽标题栏WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT等消息 都是在HandleMessage中进行处理:

1 LRESULT CMainWndDlg::HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam )
2 {
3     LRESULT lRes = 0;
4     BOOL bHandled = TRUE;
5  
6     switch( uMsg )
7     {
8     case WM_CREATE:        lRes = OnCreate(uMsg, wParam, lParam, bHandled); break;
9     case WM_NCACTIVATE:    lRes = OnNcActivate(uMsg, wParam, lParam, bHandled); break;
10     case WM_NCCALCSIZE:    lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled); break;
11     case WM_NCPAINT:       lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break;
12     case WM_NCHITTEST:     lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled); break;
13     case WM_CLOSE:         lRes = OnClose(uMsg, wParam, lParam, bHandled); break;
14     case WM_DESTROY:       lRes = OnDestroy(uMsg, wParam, lParam, bHandled); break;
15     case WM_SIZE:          lRes = OnSize(uMsg, wParam, lParam, bHandled); break;
16     case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled); break;
17     case WM_SYSCOMMAND:    lRes = OnSysCommand(uMsg, wParam, lParam, bHandled); break;
18     case WM_KEYDOWN:       PostQuitMessage(0); break;
19     default:
20         bHandled = FALSE;
21     }
22  
23     if( bHandled ) return lRes;
24     if( m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
25  
26     return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
27 }

如同代码中所示,如果消息不需要框架再处理了则直接返回。如果还需要框架处理该消息,则交由父类的HandleMessge中去处理。

 


二. 事件消息

对于系统消息我们直接重载了HandleMessage来处理,而对于鼠标点击一类的消息呢?为此,我们的窗体除了要继承CWindowWnd外,还需要继承INotifyUI,同样的重载INotifyUI类中的void Notify(TNotifyUI& msg); 函数,由该函数来处理控件操作产生的消息。但仅仅只是继承重载了还不够,我们怎么才能确保事件消息能正常传递呢?因此,在窗体创建OnCreate的时候,我们还需要添加如下m_PaintManager.AddNotifier(this); 这样,控件消息就可以传达大duilib的消息循环中,我们也就可以通过Notify函数对消息进行处理:

1 void CMainWndDlg::Notify( TNotifyUI& msg )
2 {
3     if( msg.sType == _T("windowinit") ) {
4         OnWindowInit();
5     }
6     else if( msg.sType == _T("click") ) {
7         if( msg.pSender == m_pCloseBtn ) {
8             PostQuitMessage(0);
9             return;
10         }
11         else if( msg.pSender == m_pMinBtn ) {
12             SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); return; }
13         else if( msg.pSender == m_pMaxBtn ) {
14             SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); return; }
15         else if( msg.pSender == m_pRestoreBtn ) {
16             SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); return; }
17  
18         // 按钮消息
19         OnLBtnClick(msg.pSender);
20     }
21     else if(msg.sType==_T("selectchanged"))
22     {
23         CDuiString name = msg.pSender->GetName();
24         CTabLayoutUI* pTabSwitch = static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("tab_switch")));
25         CTabLayoutUI* pDemoListSwitch = static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("demo_list_tab_switch")));
26  
27         if(name.CompareNoCase(_T("demo_tab")) == 0)
28             pTabSwitch->SelectItem(0);
29         else if(name.CompareNoCase(_T("web_tab")) == 0)
30             pTabSwitch->SelectItem(1);
31  
32         if(name.CompareNoCase(_T("demo_list_basic_ctrl")) == 0)
33             pDemoListSwitch->SelectItem(0);
34         else if(name.CompareNoCase(_T("demo_list_rich_ctrl")) == 0)
35             pDemoListSwitch->SelectItem(1);
36     }
37 }

在Notify函数中针对消息的不同进行不同的操作处理,比如click、selectchanged等等。对于这类duilib针对相关操作自定义的消息类型可以在duilib工程中的UIDefine.h文件中查看:

1 //定义所有消息类型
2 //////////////////////////////////////////////////////////////////////////
3  
4 #define DUI_MSGTYPE_MENU                   (_T("menu"))
5 #define DUI_MSGTYPE_LINK                   (_T("link"))
6  
7 #define DUI_MSGTYPE_TIMER                  (_T("timer"))
8 #define DUI_MSGTYPE_CLICK                  (_T("click"))
9  
10 #define DUI_MSGTYPE_RETURN                 (_T("return"))
11 #define DUI_MSGTYPE_SCROLL                 (_T("scroll"))
12  
13 #define DUI_MSGTYPE_DROPDOWN               (_T("dropdown"))
14 #define DUI_MSGTYPE_SETFOCUS               (_T("setfocus"))
15  
16 #define DUI_MSGTYPE_KILLFOCUS              (_T("killfocus"))
17 #define DUI_MSGTYPE_ITEMCLICK              (_T("itemclick"))
18 #define DUI_MSGTYPE_TABSELECT              (_T("tabselect"))
19  
20 #define DUI_MSGTYPE_ITEMSELECT             (_T("itemselect"))
21 #define DUI_MSGTYPE_ITEMEXPAND             (_T("itemexpand"))
22 #define DUI_MSGTYPE_WINDOWINIT             (_T("windowinit"))
23 #define DUI_MSGTYPE_BUTTONDOWN             (_T("buttondown"))
24 #define DUI_MSGTYPE_MOUSEENTER             (_T("mouseenter"))
25 #define DUI_MSGTYPE_MOUSELEAVE             (_T("mouseleave"))
26  
27 #define DUI_MSGTYPE_TEXTCHANGED            (_T("textchanged"))
28 #define DUI_MSGTYPE_HEADERCLICK            (_T("headerclick"))
29 #define DUI_MSGTYPE_ITEMDBCLICK            (_T("itemdbclick"))
30 #define DUI_MSGTYPE_SHOWACTIVEX            (_T("showactivex"))
31  
32 #define DUI_MSGTYPE_ITEMCOLLAPSE           (_T("itemcollapse"))
33 #define DUI_MSGTYPE_ITEMACTIVATE           (_T("itemactivate"))
34 #define DUI_MSGTYPE_VALUECHANGED           (_T("valuechanged"))
35  
36 #define DUI_MSGTYPE_SELECTCHANGED          (_T("selectchanged"))
37  
38 //////////////////////////////////////////////////////////////////////////

三. 消息过滤

在实际中,我们有时候可能需要根据需要对部分消息进行分类处理。比如键盘按键消息等等。对于这类情况,我们的窗体需要继承IMessageFilterUI类,重载LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)函数,同时在窗体OnCreate创建的时候添加m_pm_.AddPreMessageFilter(this)消息通知即可。

时间: 2024-11-10 07:36:03

Duilib学习笔记《05》— 消息响应处理的相关文章

Duilib学习笔记《04》— 窗体显示

在前面已经了解了duilib控件以及界面布局相关内容,接下来就要考虑该如何将xml中描述的布局通过界面展现出来.实际上在 Duilib学习笔记<01> 中我们已经简单提到过基本的流程及元素创建机制.这里我们直接用 Duilib学习笔记<03>最后提供的代码,下面我们就具体来说明: 一. duilib调用设置 1 #include "..\DuiLib\UIlib.h" 2 using namespace DuiLib; 3 #ifdef _DEBUG 4 #  

Duilib学习笔记《06》— 窗体基类WindowImpBase

在前面的例子中我们发现,窗口都是继承CWindowWnd.INotifyUI,然后重载相关函数去实现.显然,我们发现窗口的创建流程实际上都是差不多的,主要只是在OnCreate加载的配置文件不同等等-所以,能不能创建一个公有的窗体基类呢?其实,在duilib中已经提供了一个窗体基类 WindowImplBase:在基类内搭建窗口的消息框架,各处理函数为虚函数,子类可以重载处理函数,实现其处理. 此处我们以修改之前的代码为例来进行说明. 1. 窗体显示 CMainWndDlg类修改为继承Windo

Duilib学习笔记《02》— 界面布局

1. 界面描述XML文件 Duilib主要是通过XML来进行界面的布局配置,程序通过读取并解析XML文件来创建对应的窗体.DuiLib的页面布局分为三类:窗体(Window).容器(Contain)和控件(Control).顾名思义窗体就是要创建的窗口,容器则相当于是窗体内的一个子窗体,可以在容器内添加容器或者控件,当然定义的位置也都是相对与容器内的左上顶点:控件就是一些常用的Button.Edit.Label等窗体上的基本元素. 容器经常使用的有VerticalLayout(垂直布局容器).H

为duilib的MenuDemo增加消息响应,优化代码和显示效果

转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/38253297 第一部分         我在前一段时间研究了怎么制作duilib的菜单,花了几天时间以MenuDemo为基础做出个duilib的菜单以备自用,近些天在群里经常会碰到群友问如何给MenuDemo增加消息响应,为了避免重复的回答我特意写这篇日志,希望可以帮到需要之人,同时也介绍了如何美化菜单的效果.动态修改自身的状态以及通过增加属性来优化菜单的xml文件编写

Duilib学习笔记《01》— duilib整体框架认识

 从GoogleCode上下载的duilib工程中附带的一副总体设计图(如下所示),可以先整体了解一下,有个初步的认识,对后续进一步深入了解学习会很有帮助. 通过设计图有了一个初步认识后,接下来开始进一步深入学习了解,主要从以下几个方面进行了解学习:库的组成:框架基本流程:元素创建机制:消息处理机制. 1. 库的基本组成 1.1 工具库 由于duilib没有对外部的任何库进行依赖,所以在其内部实现了很多用于支撑项目的基础类(如下图所示).这些类分布在Util文件夹中: UI相关:CPoint /

EJB注释-2(EJB学习笔记之消息驱动)

消息驱动Bean消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件.一个MDB类必须实现MessageListener 接口.当容器检测到bean守候的队列一条消息时,就调用onMessage()方法,将消息作为参数传入.MDB在OnMessage()中决定如何处理该消息.你可以用注释来配置MDB 监听哪一条队列. 消息驱动Bean的服务器 @MessageDriven(activationConfig =...{       @ActivationConfigProperty(pr

scala 学习笔记(05) OOP(中)灵活的trait

trait -- 不仅仅只是接口! 接上回继续,scala是一个非常有想法的语言,从接口的设计上就可以发现它的与众不同.scala中与java的接口最接近的概念是trait,见下面的代码: package yjmyzz object App { def main(args: Array[String]) { val bird = Bird("pigeon") bird.fly println(bird.isInstanceOf[Bird]) //true println(bird.is

C#开发WINDOWS应用程序时消息的处理(C#学习笔记之二)

作者:浙江省温岭市电信局 王骏WINDOWS应用程序是靠消息驱动的,在VC中我们通过CLASSWIZARD可以为某窗口类添加消息处理函数,CLASSWIZARD将为你添加消息映射,对于WINDOWS消息,生成的消息处理函数重载了基类的虚拟方法.而在C#中如何处理消息呢?本文针对VS.NET BETA1环境下的C#简单地介绍WINDOWS消息以及自定义消息的处理方法.示例代码下载 17K一.生成一个名为MSGApplication的工程工程的建立方法请参考:C#学习笔记之一二.处理WM_PAINT

Spring学习笔记3之消息队列(rabbitmq)发送邮件功能_java

rabbitmq简介: MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术.排队指的是应用程序通过 队列来通信.队列的使用除去了接收和发送应用程序同时执行的要求.其中较为成熟的MQ产品有IBM WEBSPHERE MQ. 本节的内容是用户注册时,将邮