从GoogleCode上下载的duilib工程中附带的一副总体设计图(如下所示),可以先整体了解一下,有个初步的认识,对后续进一步深入了解学习会很有帮助。

通过设计图有了一个初步认识后,接下来开始进一步深入学习了解,主要从以下几个方面进行了解学习:
库的组成;框架基本流程;元素创建机制;消息处理机制。

1. 库的基本组成

1.1 工具库

由于duilib没有对外部的任何库进行依赖,所以在其内部实现了很多用于支撑项目的基础类(如下图所示)。这些类分布在Util文件夹中:

  • UI相关:CPoint / CSize / CDuiRect
  • 简单容器:CStdPtrArray / CStdValArray / CStdString / CStdStringPtrMap

上面这些类看名字就基本能够理解其具体的含义了,当然除了基本的基础库,还有一些和窗口使用相关的工具的封装,如窗口工具:WindowImplBase,这个工具我们在这里不详述,后面使用中会经常用到。

1.2 控件库

控件库在duilib的实现中被分为了两块:Core和Control:

  • Core中包含的是所有控件公用的部分,里面主要是一些基类和绘制的封装。
  • Control中包含的就是各个不同的控件的行为了。

这当中尤其要注意控件基类CControlUI和容器基类CContainerUI,这是duilib核心类(如下图所示)中是很重要的两部分:

1.2.1. 控件基类:CControlUI

CControlUI在整个控件体系中非常重要,它是所有控件的基类,也是组成控件树的基本元素,控件树中所有的节点都是一个CControlUI。
        它基本包括了所有控件公共的属性,如:位置,大小,颜色,是否有焦点,是否被启用等等。当然这个类中还提供了非常多的基础函数,用于重载来实现子控件,如获取控件名称和ClassName,是否显示等等。
        另外为了方便从XML中直接解析出控件的各个属性,这个类中还在提供了一个SetAttribute的方法,传入字符串的属性名称和值对特定的属性进行设置,内部其实就是挨个比较字符串去完成的,所以平时使用的时候就还是不要使用的比较好了,因为每个属性实际上都有特定的方法来获取和设置。
        另外每个控件中还有几个事件管理的对象——CEventSource,这些对象会在特定的时机被触发,如OnInit,调用其中保存的各个回调函数。

1.2.2. 容器基类:CContainerUI

有了基本的控件基类之后,我们就需要容器来将他管理起来,这个容器就是CContainerUI,其内部用一个数组来保存所有的CControlUI的对象,后续的所有工作,就都是基于这个对象来进行的了。
这样在CContainerUI里面,主要实现了一下几个功能:

  • 子控件的查找:CContainerUI::FindControl
  • 子控件的生命周期管理:是否销毁(在Remove的时候自动销毁) / 是否延迟销毁(交给CPaintMangerUI去一起销毁)。
  • 滚动条:所有的容器都支持滚动条,在其内部会对键盘和鼠标滚轮事件进行处理(CContainerUI::DoEvent),对其内部所有的元素调整位置,最后在绘制的时候实现滚动的效果
  • 绘制:由于容器中有很多元素,所以为了加快容器的绘制,绘制的时候会获取其真正需要绘制的区域,如果子控件不在此区域中,那么就不予绘制了

而对于这些控件的绘制实现以及相关使用,在后续具体进一步学习中再深入详解。


2. 框架基本流程

框架的基本流程实际上类似Win32创建窗口流程,如果对于Win32比较熟悉,这部分可以很快掌握。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{CPaintManagerUI::SetInstance(hInstance);        // 第一步: 实例句柄与渲染类关联CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin"));HRESULT Hr = ::CoInitialize(NULL);              // 第二步:初始化COM库, 为加载COM库提供支持if( FAILED(Hr) ) return 0;CMainFrameWnd* pFrame = new CMainFrameWnd();    // 第三步:创建窗口类if( pFrame == NULL ) return 0;pFrame->Create(NULL, _T("主程序"), UI_WNDSTYLE_FRAME, 0L, 0, 0, 800, 600); // 第四步:注册窗口类与创建窗口//  实际上这里调用Create操作和Win32创建窗体一样,内部实际上做了以下操作://  -> RegisterSuperclass (注册一个超类 即已有一个窗口类的基上再注册一个窗口类)//  -> RegisterWindowClass (注册窗口类)//  -> ::CreateWindowEx (创建窗口,此时触发 WM_CREATE 消息)//  -> HandleMessage  ( WM_CREATE消息处理OnCreate)pFrame->CenterWindow();          // 第五步:窗口居中显示::ShowWindow(*pFrame, SW_SHOW);CPaintManagerUI::MessageLoop(); // 第六步:处理消息循环::CoUninitialize();             // 第七部:退出程序并释放COM库return 0;
}

3. 元素创建机制

第一步:响应WM_CREATE消息;

第二步:主窗口类与窗口句柄关联;

m_pm.Init(m_hWnd)

第三步:加载XML并动态创建界面无素,与布局界面元素

CDialogBuilder builder;</span>CDialogBuilderCallbackEx cb;</span>CControlUI* pRoot =builder.Create(_T("skin.xml"), (UINT)0,  &amp;cb, &amp;m_pm);

第四步:附加控件到HASH表

PaintManagerUI::AttachDialogInitControlsFindControl__FindControlFromNameHashpManager-&gt;m_mNameHash.Insert

第五步:添加通知处理

CPaintManagerUI::AddNotifier

第六步:窗口的绘制(以上是窗口的创建过程,通过xml,所有控件都被加载到CPaintManagerUI)

CPaintManagerUI响应WM_PAINT消息,开始双缓存绘图m_pRoot->DoPaint绘背景图 CControlUI::DoPaintCRenderEngine 真正的绘图类pPostPaintControl->DoPostPaint 在背景图上绘制控件::BitBlt 把离屏视图画到主屏上

4.消息处理机制

 第一步:注册消息处理函数

在CWindowWnd注册窗口(RegisterWindowClass())里,注册消息回调函数(__WndProc);

第二步:消息分发

消息回调函数(处理所有系统发送的消息),然后回调函数通过子类的CMainFrameWnd::HandleMessage对消息进行分发。

非窗口消息通过CMainFrameWnd::HandleMessage调用CPaintManagerUI::MessageHandler进行分发。

第三步:消息循环

在CPaintManagerUI类的MessageLoop处理消息循环;

接收到消息以后,进入消息回调函数(__WndProc);

(注:以下内容以鼠标单机Button事件为例)

第四步:处理控件消息

鼠标按下时(WM_LBUTTONDOWN),查找鼠标点击的控件。

处理控件的鼠标按下消息:通过调用基类CControlUI:: DoEvent,引起子类如CButtonUI::DoEvent事件。

子类的DoEvent对不同类型的事件进行处理。通过CPaintManagerUI:: SendNotify回调控件注册的事件。

本文转载自:https://www.cnblogs.com/MrYuan/p/4971842.html

duilib整体框架认识相关推荐

  1. 基于360SafeDemo对duilib整体框架的概述

    我们以一个具体窗口(360Safe Window)的创建为入口,建立起程序的整个框架.然后逐步深入,对其中的细节以及duilib中各个类在任务的执行过程中负责的任务进行分析.分析以问题作为导向,随着层 ...

  2. 【推荐系统】推荐系统整体框架概览

    感谢博文作者 Kevin_Duan 原文链接:https://blog.csdn.net/chunyun0716/article/details/83152037 推荐系统整体架构 先说点题外话,最近 ...

  3. 通俗易懂SpringMVC整体框架理解

    最近又重新温习了一下前台SpringMVC框架,能够从整体上对SpringMVC有一个全局的认识.在这里也总结一下,为那些即将学习SpringMVC的亲们,做一个很好的开端吧! 1. SpringMV ...

  4. V4L2 driver(一). 整体框架

    1.1 从字符设备说起 熟悉v4l2用户空间编程的都知道, v4l2编程主要是调用一系列的ioctl函数去对v4l2设备进行打开, 关闭, 查询, 设置等操作. v4l2设备是一个字符设备, 而且其驱 ...

  5. 推荐系统整体框架概览

    推荐系统整体框架概览 推荐系统整体架构 推荐系统的核心组成部分 离线 核心节点 服务 UI 总结 推荐系统整体架构 先说点题外话,最近在看的书中讲到了怎么进行自学的方法,分了十个层级.第一个便是要了解 ...

  6. 浅谈opencl之整体框架

    结合四大模型,以CPU和GPU平台为例子,opencl整体框架如下: CPU为host端, GPU为device端, host和device端的交互是以context为主.context贯穿到整个op ...

  7. jQuery源码分析 整体框架部分及部分常用方法

    最近尝试看看jQuery的源码. 版本 version = "1.11.1" 相对于看一本jQuery如何使用的书,看jQuery源码对它可以有更深层次的理解.jQuery中大量使 ...

  8. 第一次总结:整体框架

    第一次总结:整体框架 tcp部份: 1.初始化WiFi连接路由器 wifi.begin();bool b = wifi.Initialize(STA, SSID, PASSWORD);连接局域网if( ...

  9. zeptojs库解读1之整体框架

    首先看的是整体框架, // zepto骨骼,这个函数的作用使得Zepto(slector, context)使用很多$.fn里面的方法 var Zepto = (function(){// zepto ...

  10. 项目背景一般写什么_项目申报整体框架规划思路,提高你的书写逻辑!

    看到网友留言,希望我能分享下项目申报整体框架规划的思路,我们今天就这个内容深度讨论. 当我们拿到企业的所有材料的时候,第一件事情就是要看材料是否满足必须的申报条件,缺一不可,满足了这些条件,如果缺少一 ...

最新文章

  1. MyBatis映射文件(一)
  2. php 获取下拉框选中的文本,jQuery如何获取select选择的文本与值?(代码示例)...
  3. JavaWeb学习中的小问题
  4. thymleaf中枚举 判断对象值内容
  5. Android中Adapter适配器的介绍以及用法的总结
  6. linux python2.7安装教程_Linux RedHat下安装Python2.7开发环境
  7. linux桌面隐藏鼠标,如何隐藏鼠标光标
  8. VC++用异或(XOR)方式实现拖放画动态直线
  9. Spring包名代码提示
  10. 失焦事件触发_JavaScript event 事件详解
  11. Atitit 字符串转换数组main参数解析 args splitByWholeSeparator String string= -host 101.1 8*124 -db 1
  12. 从幼苗长成大树 中美两国GIS软件技术已并驾齐驱
  13. java.lang.IllegalStateException: No instances available for user
  14. python海龟画图函数汇总
  15. 浙江大学副教授杨洋——《Time2Graph:从图视角出发的时间序列建模》
  16. surface book 3 结束休眠之后风扇狂转
  17. 未明学院:国际政治专业出身,如何pk掉港大、美籍商科生,拿下亚马逊市场部德勤offer!
  18. excel之高级筛选与VLOOKUP函数
  19. 金融工程学(一):概述
  20. m.555lu.co/vlist.php_新浪微博V2接口演示程序-Powered by Sina App Engine

热门文章

  1. mysql5.7.13编译安装_编译安装MySQL-5.7.13
  2. python关于csv的查询系统_使用Python对csv文件操作
  3. sql 语句 查询结果赋值变量_RationalDMIS 7.1 变量赋值 ASSIGN语句
  4. mysql 命令 kill_当MySQL事务中发生了网络异常
  5. latex数学符号加粗_latex的安装与数学公式的书写
  6. In file included from /usr/include/stdio.h:27:0, from btest.c:16: /usr/include/feat出错的解决办法
  7. oracle通信通道的文件结尾_oracle里执行full join 报通信通道的文件结尾问题
  8. php中js中文传值乱码,php解析JSON中文乱码问题的解决方法
  9. A. Death Note
  10. 如何系统嗯学习计算机知识,老师,非科班出身的人该怎么系统的学习计算机知识呢?...