接下来,我们继续分析UIlib.h文件中余下的文件,当然部分文件可能顺序错开分析,这样便于从简单到复杂的整个过程的里面,而避免一开始就出现各种不理解的地方。

  1. UIManager.h:UI管理器,暂时放在后面介绍;

  2. UIBase.h:UI窗口相关,包括常用的窗口风格、窗口类风格的宏定义,调试相关,以及基本窗口类;

    首先宏定义了几个常用的窗口风格、窗口扩展风格和窗口类风格,以UI_WNDSTYLE_XXX和UI_CLASSSTYLE__XXX开头的;

    ASSERT采用的是CRT的_ASSERTE、DUI__Trace、DUI__TraceMsg用以调试、跟踪消息,不过注意DUI__Trace字符串长度不能超过300字节;

    CNotifyPump:通告消息泵,用以对消息分发、下发(主要是对继承树的各个添加到_messageEntries的消息映射遍历分发,并执行相应的处理函数),数据成员:m_VirtualWndMap:

    虚拟窗口的集合,类型CStdStringPtrMap可以较为快速查找,此外可能增加了虚拟窗口,此时便先对虚拟窗口分发,若处理则直接返回,否则再遍历主窗口,成员函数:AddVirtualWnd:

    添加虚拟窗口,参数strName、pObject分别为虚拟窗口名称与该虚拟窗口的消息通告泵对象,RemoveVirtualWnd:移除指定名称的虚拟窗口,NotifyPump:通告泵,实现真正的消息

    分发操作(先对虚拟窗口分发,再对主窗口遍历分发),LoopDispatch:循环分发消息(对消息继承树和_messageEntries遍历,并对应消息处理类型,调用执行相应的消息处理接口);

    CWindowWnd:窗口基类,将Win32的创建窗口的主要过程进行了封装,一些控件可能会从它继承实现;先从数据成员:m_hWnd:窗口句柄,m_OldWndProc:早期的窗口消息

    处理函数地址,m_bSubclassed:是否为子类化的窗口类,成员函数:构造函数CWindowWnd:其中m_OldWndProc初始化为默认窗口处理函数::DefWindowProc,GetHWND:

    获取当前窗口句柄,同重载的运算符operator HWND(),RegisterWindowClass:注册窗口类,暂时提供一个默认值的窗口类,重点关注其中的__WndProc的消息处理函数,可以发现

    很熟悉的操作,对是这样的,他把本类对象保存在GWLP_USERDATA窗口关联的用户数据中了,便于下次可直接取出(但保证其他地方不再更新该GWLP_USERDATA的用户数据),

    RegisterSuperclass:注册子类化的窗口类,从一个已存在的窗口中获取到WNDCLASSEX信息,此外其消息处理函数__ControlProc:内部处理方式不再是使用GWLP_USERDATA

    关联,而是使用SetProp设置窗口属性表项,来保存本来对象,便于下一次GetProp取出本类对象,调用本类的非静态成员消息处理函数;Subclass:子类化窗口类,内部调用

    SubclassWindow实现窗口子类化(事实上内部调用的还是SetWindowLongPtr((hwnd), GWLP_WNDPROC, (LPARAM)(WNDPROC)(lpfn),这样用__WndProc接管消息处理,此外

    还调用了SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(this))用来保存本类对象,便于后期消息处理,Unsubclass:卸载窗口子类化:使用原消息

    处理函数来接管消息处理;综上,本类中子类化窗口的方式有:1. 通过GetSuperClassName获取已注册的父类窗口类名,再获取WNDCLASSEX信息,并通过__ControlProc来处理消息;

    2. 使用Subclass,传入已创建好的窗口句柄,这样通过SubclassWindow和SetWindowLongPtr来达到hook消息的目的,多个版本的Create函数与CreateDuiWindow:创建窗口的过程:

    获取超类类名,若已经给予,则调用RegisterSuperclass注册新的窗口类(主要是为了继承部分窗口类的属性),若未给予超类类名,则调用RegisterWindowClass注册一个默认值的窗口类,

    此后调用CreateWindowEx创建该窗口,ShowWindow:显示或隐藏当前窗口,ShowModal:模拟MFC中的对话框DoModal函数的处理流程;可以看到将拥有者窗口变得不可用,并使得

    当前窗口显示,此后内部使用自己的一套消息泵来从线程消息队列中获取消息,当内部消息泵收到本窗口消息WM_CLOSE或是WM_QUIT消息则会退出消息泵,并使得父窗口可用并获取到焦点

    ,另外对于消息WM_QUIT消息,需要将该消息转发给拥有者窗口(不一定是父窗口),使得拥有者窗口可被销毁(因为能跳出内部的GetMessage并得到WM_QUIT消息,则为销毁拥有者窗口);

    Close:关闭窗口,内部使用::PostMessage(WM_CLOSE)实现,发送消息到该线程的消息队列中直接返回;另外SendMessage:内部使用SendMessage发送消息到消息对应处理函数处理

    并等待处理再返回;CenterWindow:居中显示窗口,内部处理了多显示器的情况,若存在拥有者窗口,则获取拥有者窗口所在显示器大小并使得该窗口居中显示,SetIcon:设置当前窗口的

    大小图标,内部调用LoadImage(旧用LoadIcon,被替代)加载资源ID:nRes,不过这里需要批评一下之前定义了STRINGorID类型,其实这里可以直接来用的,ResizeClient:调整窗口客户

    区域大小,内部调用了AdjustWindowRectEx设置客户区域大小并获取调整后所得到的窗口区域大小,并通过SetWindowPos设置窗口大小;HandleMessage:成员消息处理函数,真实地

    接管消息处理不过内部目前只是调用CallWindowProc暂时使用m_OldWndProc来处理消息,此外一个比较有用的消息处理函数OnFinalMessage,专门用来在窗口销毁后的最后一个消息

    WM_NCDESTROY中处理其他的资源销毁的任务,这样外部就可以无需显示的调用当前窗口类的析构函数来销毁内部内核资源或其他资源了,很方便的;最后该类基本完成了一个基本的窗口类

    其他需要特殊处理的窗口类可以继承该类实现自己的操作,如后面介绍的WindowImplBase类。

  3. UIControl.h:UI控件基类,主要实现了控件相关如文本、图形、位置、菜单等属性设置

    FINDCONTROLPROC:声明的控件查找函数,CControlUI* (CALLBACK* FINDCONTROLPROC)(CControlUI*, LPVOID),用在回调查找中;

    CControlUI:UI控件基类,大部分控件实现继承于该类,因该类比较大,所以我们在分析的时候,建议先从成员函数开始;构造函数初始化了一系列的数据成员,暂不理会,后面涉及到相关数据成员

    时再回头看看即可,析构函数~CControlUI:可以看到内部OnDestroy为我们之前分析的事件源,控件析构的时候需要处理的OnDestroy事件,此外调用了CPaintManagerUI管理的释放该UI对象

    消息通告和计时器,这样消息不会再发给当前已被释放的UI对象,GetName/SetName:获取/设置控件的名称m_sName,GetClass:获取控件类名称"ControlUI",子类一般会重写该函数,

    GetInterface:用以根据pstrName匹配获取当前对象的继承层次中的指针对象,GetControlFlags:获取控件标记(取UIFLAG_TABSTOP、UIFLAG_SETCURSOR、UIFLAG_WANTRETURN)

    Activate:当前控件是否为激活的状态(可见并可用),GetManager:获取管理当前UI控件的CPaintManagerUI对象m_pManager,SetManager:设置管理该UI的m_pManager、父控件,此外若

    提供了需要初始化处理操作的事件源OnInit,再此将执行该事件源,GetParent:获取当前控件的父控件,GetText/SetText:获取/设置当前控件的文本并更新继承控件树控件大小,GetBkColor/

    GetBkColor2/GetBkColor3/SetBkColor/SetBkColor2/SetBkColor3/:设置背景色(提供三色,具体作用后面介绍),GetBkImage/SetBkImage:获取/设置背景图片,GetFocusBorderColor/

    SetFocusBorderColor:获取/设置焦点时边框颜色,IsColorHSL/SetColorHSL:获取/设置是否开启HSL色彩模式,GetBorderRound/SetBorderRound:获取/设置边框圆角大小,

    DrawImage:绘制图像,参数hDC将要绘制到的控件或窗体画刷句柄,pStrImage为图形内容字符串(含文件名或资源名等),函数内部根据内容字符串解析并调用CRenderEngine渲染引擎绘制,具体

    操作过程后面分析,GetBorderSize/SetBorderSize:获取/设置圆角边框画笔大小m_nBorderSize(命名也是醉了,含义不清与m_cxyBorderRound容易冲突),GetBorderColor/SetBorderColor:

    获取/设置圆角边框颜色,SetLeftBorderSize/SetTopBorderSize/SetRightBorderSize/SetBottomBorderSize:设置/获取左边框、上边框、右边框、下边框画笔大小,SetBorderStyle:设置边框

    画笔风格,SetPos/GetPos:设置/获取控件位置,m_rcItem,GetWidth/GetHeight/GetX/GetY:获取控件宽度、高度、左位置、上位置(左上位置),SetPadding/GetPadding:设置填充区域

    m_rcPadding,似乎内部未曾使用该变量,SetFixedXY/SetFixedWidth/SetFixedHeight:设置预设值控件的大小、宽度、高度,一般通过SetPos与GetPos获取到实际的大小,此外SetMinXXX系列

    函数设置最小最大宽度、高度,SetRelativePos/SetRelativeParentSize:设置父控件、相对父控件的相对位置,SetToolTip/GetToolTip:设置信息提示,鼠标停留时的提示框信息,SetToolTipWidth:

    设置信息框宽度,SetShortcut/GetShortcut:设置控件快捷键key,SetContextMenuUsed:设置是否使用菜单上下文,SetUserData/GetUserData:设置/获取用户数据,SetTag/GetTag:设置/

    获取标记数据,SetVisible:设置是否显示,SetEnabled:设置是否可用,SetMouseEnabled:设置鼠标是否可用,SetKeyboardEnabled:设置键盘是否可用,SetFocus:设置是否为焦点,

    SetFloat:设置是否可停浮,FindControl:查找控件,并执行Proc回调函数,Invalidate:使无效,重绘,NeedUpdate/NeedParentUpdate:需要更新重绘或父控件继承树重绘,GetAdjustColor:

    获取调整后的色彩,Init、DoInit:执行初始化操作,其中OnInit提供初始化事件源,Event、DoEvent:执行事件操作,其中OnEvent提供事件源,SetAttribute:设置控件属性,ApplyAttributeList

    :设置属性列表,内容包含各种可能的属性字符串,解析并调用SetAttribute设置各属性,EstimateSize:获取预设值控件大小,DoPaint:绘制操作,主要执行背景颜色、背景图、状态图、文本、边框

    等,PaintBkColor/PaintBkImage/PaintStatusImage/PaintText/PaintBorder:分别为绘制背景色、背景图片、状态图、文本、绘制边框,DoPostPaint:绘制相应控件大小至HDC,布局中用到,

    SetVirtualWnd /GetVirtualWnd:设置/获取虚拟窗口;目前大部分成员函数和成员数据说明,一部分函数用以外部调用接口,一部分用于内部绘制操作,此外也有部分参数未曾用到或是用以控制绘制,

    接下来说说数据成员:公有成员5个事件源:OnInit、OnDestroy、OnSize、OnEvent、OnNotify,分别为初始化源、释放源、大小位置改变源、事件源、通告源,受保护成员:m_pManager:绘制

    管理器对象,m_pParent,父控件对象,m_sVirtualWnd:虚拟窗口,m_sName:控件名称,m_bUpdateNeeded:是否需要更新控件,m_bMenuUsed:是否使用菜单上下文,m_rcItem:

    控件位置,m_rcPadding:控件填充大小,m_cXY:控件预设值位置大小,m_cxyFixed:控件固定大小,m_cxyMin、m_cxyMax:预设值最小、最大值,m_bVisible:是否可显示,此外还有一个

    m_bInternVisible:内部使用的是否可显示控件,用在某些继承的控件实现中需要用到的,m_bEnabled:控件是否可用,m_bMouseEnabled:鼠标是否可用,m_bKeyboardEnabled:键盘是否

    可用,m_bFocused:是否获取到焦点,m_bFloat:是否可停浮,m_bSetPos:是否在设置控件位置大小,m_tRelativePos:与父控件关联位置,m_sText:设置文本,m_sToolTip:设置信息提示

    m_chShortcut:快捷键CHAR,m_sUserData:用户保存的数据字符串,m_pTag:用户保存的标记,m_dwBackColor:背景色,m_sBkImage:背景图片,m_sForeImage:前景图片,

    m_dwBorderColor:边框颜色,m_dwFocusBorderColor:获取到焦点时边框颜色,m_bColorHSL:是否启用HSL色彩模型,m_nBorderSize:边框画笔大小,m_nBorderStyle:边框画笔风格,

    m_nTooltipWidth:提示信息框宽度,m_cxyBorderRound:圆角边框大小,m_rcPaint:绘制区域大小,m_rcBorderSize:边框位置大小;

  基本上对整个类进行了概括性的说明,更为详尽的比如:绘制场景、细节、布局等将在后期分析,目前我们只需要有个大概的概念即可。

    

    

    

Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备二)的更多相关文章

  1. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备四)

    接下来,分析uilib.h中的WinImplBase.h和UIManager.h: WinImplBase.h:窗口实现基类,已实现大部分的工作,基本上窗口类均可直接继承该类,可发现该类继承于多个类, ...

  2. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备三)

    接下来,我们将继续分析UIlib.h文件中其他的文件, UIContainer.h, UIRender.h, WinImplBase.h, UIManager.h,以及其他布局.控件等: 1. UIR ...

  3. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备一)

    上节中提到在遍历创建控件树后,执行了以下操作:      1. CDialogBuilder构建各控件对象并形成控件树,并返回第一个控件对象pRoot:     2. m_pm.AttachDialo ...

  4. Duilib源码分析(四)绘制管理器—CPaintManagerUI

    接下来,分析uilib.h中的UIManager.h,在正式分析CPaintManagerUI前先了解前面的一些宏.结构: 枚举类型EVENTTYPE_UI:定义了UIManager.h中事件通告类型 ...

  5. Duilib源码分析(三)XML解析器—CMarkup

    上一节介绍了控件构造器CDialogBuilder,接下来将分析其XML解析器CMarkup: CMarkup:xml解析器,目前内置支持三种编码格式:UTF8.UNICODE.ASNI,默认为UTF ...

  6. Duilib源码分析(六)整体流程

    在<Duilib源码分析(一)整体框架>.<Duilib源码分析(二)控件构造器—CDialogBuilder>以及<Duilib源码分析(三)XML解析器—CMarku ...

  7. Duilib源码分析(一)整体框架

    Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析):通过XML布局界面,将用户界面和处理逻辑彻底 ...

  8. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  9. Memcached源码分析之内存管理

    先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到). 一)模型分析在开始解剖memcached关于内存管 ...

随机推荐

  1. 精通css 高级web标准解决方案——可视化格式模型-定位模型

    CSS 中有三种定位机制:普通流.浮动.绝对定位.(默认为普通流) 改变文档流:display: inline-block; (支持到ie8及以上) 1-匿名块框: <div> 你好! & ...

  2. Scanner类

    Scanner类:用于获取用户的键盘输入 成员方法: public boolean hasNextXxx():判断是否某种类型的元素 public Xxx nextXxx():获取该元素 常用方法: ...

  3. Linux知识:/root/.bashrc与/etc/profile的异同

    Linux知识:/root/.bashrc与/etc/profile的异同 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shel ...

  4. FlumeNG 笔记

    环境:CentOS6.6 64位 + FlumeNG 1.6 请参考推荐文档: Flume-ng的原理和使用 - JunezChen Blog - SegmentFault  https://segm ...

  5. .htaccess语法之RewriteCond与RewriteRule指令格式详细解释

    htaccess语法之RewriteCond与RewriteRule指令格式详细解释 (2012-11-09 18:09:08) 转载▼ 标签:  htaccess it 分类: 网络 上文htacc ...

  6. 补发:用Meal Prep+模块化饮食来减肥之实操

    自从上次读到仰望尾迹云 老师的模块化饮食的帖子,再了解了一些Meal Prep的内容,结合着做Meal Prep健康餐至今已经快一个半月了.整体感觉还可以,所以在这里讲一下自己的心得体会. 分为三个部 ...

  7. yum 操作复习

    RPM与YUM是配合使用的. rpm负责从网站或指定的文件路径,获取到rpm软件包.也就是说你要安装什么服务或软件,就要先找到rpm包,下载下来.也就是通常说的配置yum源. 啥是yum源.你下载下的 ...

  8. 如何配置IIS处理多并发请求及存在的问题

    很多时候多线程能快速高效独立的计算数据,应用比较多. 但今天遇到的多进程下的问题更是让人觉得复杂 多进程下static变量都要失效,就目前的平台和产品static使用是很多的,各种session.ca ...

  9. MFC双缓存技术代码

    屏蔽背景刷新,在View中添加对WM_ERASEBKGND的响应,直接返回TRUE: BOOL CTEMV1View::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息 ...

  10. 天河微信小程序入门:阿里云tomcat免费配置https

    天河君在第一时间通过了微信小程序验证,开启了我的微信小程序之旅.因为天河君之前是一名后端狗,对前端不是很了解,所以几乎可以认为是从零开始学做微信小程序.也希望有志在微信小程序方向做点事情的朋友能够和我 ...