DUI lib学习总结

windows系统的消息交互流程

1. DUI lib定义
  • DUI lib:是一款基于DiretUI技术的轻量级windows界面库,以xml文件形成界面布局,具备界面风格绚丽,兼容ActiveX控件等特点;
  • DirectUI技术:Paint on parent dc directly,即直接在父窗口上绘图,左右子窗口不以窗口句柄形式存在,只是逻辑上的窗口;
  • DUI lib与MFC相比,MFC界面不美观,界面细节难处理,使用硬编码,开发效率低,使用hook技术可能导致系统不稳定;DUI只依赖于GDI。
  • DUI lib提供了所见即所得的开发工具UIDesigner,开发者可自行设计UI;
  • DUI界面与逻辑处理分离。

2. Duilib库界面显示流程框架
在Duilib中,WindowImplBase 这个类代表了图中 “CWndClass”。
所以我们需要做的是:
1)生成一个XML。
2)生成一个WindowImplBase对象。
3)加载XML。
4)显示窗口。
但是编写的时候,WindowImplBase已经帮我们做了许多工作,我们只需要指定XML路径,它就能够帮助我们自动加载,非常方便。
再次强调:把duilib当作一个类库用,而不是一个语言、IDE、框架。

3. 基于DUI lib的业务窗口结构层次
(1) DUI lib核心类(位于源码core文件夹中)
<1> CWindowWnd,所有业务窗口的父类,管理窗口对象(UIBase.h)
主要作用:
  • 负责创建窗口,调用windows系统API--CreateWindowEx;
  • 负责注册窗口(RegisterWindowClass),设置窗口处理过程(__WndProc);
  • 提供窗口子类化与超类化接口。

<2> CDialogBuilder,控件布局类(UIDlgBuilder.h)
主要作用:
  • 对去XML脚本,构建控件树(在CWindowWnd处理系统返回的WM_CREATE消息时构建该对象,并构建控件树);
  • 创建控件对象。

<3> CPaintManagerUI,窗口消息及UI绘制管理类,与窗口绑定,作为WindowImplBase对象的成员变量(UIManager.h)
主要作用:
  • 绘制控件,拥有设置获取控件信息的接口;
  • 消息管理,拥有窗口的消息循环,存储了控件消息处理函数与控件名称之间的映射关系;
  • 事件通知,对于UI消息,通过维护的映射关系,将消息通知给对应的处理函数。

<4> INotifyUI,事件通知抽象类(UIManager.h)
主要作用:
  • 重载Notify虚函数,处理事件通知,它是实现消息映射的关键,是DUI lib中实现消息传递给控件处理函数的关键。(CPaintManagerUI::MessageHandler中遍历m_aNotifiers进行消息通知)

(2) 控件类
<1>CControlUI,所有控件类的基类,负责提供通用控件属性管理;
<2>CLabelUI,静态标签类,衍生类有:CButtonUI、CTextUIdeng等;
<3>CContainerUI,容器类,衍生类有:CVerticalLayoutUI、 CHorizontalLayoutUI等;

4. DUI lib中相关接口的理解
<1>CWindowWnd中的HandleMessage(用于截获消息)
用于处理系统回调窗口处理过程的消息 ,一般DUI lib的基类中处理了各种消息,所以当业务窗口无需特殊消息处理时,无需重写此接口,只有需要处理特殊消息是才重写;
<2>IMessageFilterUI中的MessageHandler(用于截获消息)
用于过滤一些UI需要特殊处理的消息, 在WindowImplBase中HandleMessage里面调用m_PaintManager.MessageHandler, 而在m_PaintManager中遍历m_aMessageFilters表,将消息过滤给向监听特殊消息的UI窗口( 可在业务窗口中显示调用m_PaintManager的AddMessageFilter进行过滤消息handler注册, 在DUI lib的实现中,是在WindowImplBase处理WM_CREATE消息时,调用AddPreMessageFilter进行注册的,存储于m_aPreMessageFilters,然后在CPaintManagerUI的MessageLoop中调用TranslateMessage,通过遍历集合调用PreMessageHandler进行消息的截获与提前处理 ),所以UI无特殊消息需要过滤处理的,一般不重写此函数;
<3>INotifyUI中的Notify(用于通知消息给监听者)
在m_PaintManager.MessageHandler中会遍历监听者集合m_aNotifiers用于传递消息给监听者(在WindowImplBase中处理WM_CREATE消息时,调用 m_PaintManager.AddNotifier进行注册);
<4>WindowImplBase中的HandleCustomMessage(用于截获消息)
用于处理用户自定义消息。

5. DuiLib消息响应方式:
<1>实现IMessageFilterUI接口,在业务窗口类中调用CPaintManagerUI::AddPreMessageFilter进行注册,在消息发送到窗口处理过程前的过滤,并进行特殊处理;
<2>重载HandleMessage函数,当消息发送到窗口过程中时,最先进行过滤。
<3>实现INotifyUI,调用CPaintManagerUI::AddNotifier(窗口创建时会调用,在基类实现了),将自身加入Notifier队列。
<4>添加消息代理(其实就是将成员函数最为回到函数加入),MakeDelegate(this, &CFrameWindowWnd::OnAlphaChanged);,当程序某个地方调用了 CPaintManagerUI::SendNotify,并且Msg.pSender正好是this,我们的类成员回调函数将被调用。
<5>重载父类:WindowImplBase::HandleCustomMessage函数
<6>使用类似MFC的消息映射,DUI lib中将其定义为宏,例如:

6. DUI lib中实现原生的窗口消息转发给控件的原理
主要是WindowImplBase的HandleMessage中会调用CPaintManagerUI的MessageHandler处理各类消息(如鼠标点击),而在MessageHandler中会遍历所有的消息监听者,将消息发给对应的控件,若控件是激活状态,则调用CPaintManagerUI的SendNotify将消息发给对应的控件,控件内部的消息映射再将消息传给处理函数。

7. DUI lib使用经验总结
(1)DUI lib颜色设置
在设置控件的bkcolor时,一般是用#加6位数字表示颜色,如果需要表示透明度,则是在前面再加两位数,即颜色从0-255。
(2)UI布局思路
可通过将窗口划分区域的方式进行布局,将无用的区域用Control进行填充。
(3)自定义拖动控件
借助Duilib本身的能力,我们的自定义控件需要完成以下两个函数的重载:
  • DoEvent:在此接口中,主要处理三个事件:
UIEVENT_BUTTONDOWN:获取鼠标点击时的坐标,和控件位置信息
UIEVENT_BUTTONUP:用新位置绘制控件
UIEVENT_MOUSEMOVE:记录鼠标移动的坐标,计算新位置
  • DoPostPaint
(4) 制作渐变消失的窗口(控件)
方案:可以通过调整窗口背景颜色的透明度才实现,即每隔一定时间就降低透明度,直到透明度为0时,将窗口或控件隐藏即可。

参考博客链接:
http://blog.csdn.net/u012108436/article/details/44993675
http://blog.csdn.net/mergerly/article/details/8560428
http://www.cnblogs.com/Alberl/p/3354459.html
http://blog.csdn.net/qq_28098067/article/details/5298122

你可能感兴趣的:(DUI学习笔记)