一、Duilib中各个类的简单介绍
DirectUI意为直接在父窗口上绘图(Paint on parent dc directly)。即子窗口不以窗口句柄的形式创建(windowless),只是逻辑上的窗口,绘制在父窗口之上。微软的“DirectUI”技术广泛的应用于Windows XP、Vista、Windows 7,如浏览器左侧的TaskPanel,控制面板导航界面,Media Player播放器,即时通讯工具MSN Messager等。
DirectUI好处在于可以很方便的构建高效、绚丽的、非常易于扩展的界面。国外如微软,国内如腾讯、百度等公司的客户端产品多采用这种方式来组织界面,从而很好的将界面和逻辑分离,同时易于实现各种超炫的界面效果如换色、换肤、透明等。
DirectUI可以理解为一个轻量级的WPF,可以让C++做出C#般绚丽的界面。目前国内做DirectUI皮肤库的公司主要有两家:第一家是UIPower(即Skin++的公司),网址www.uipower.com,其DirectUI产品网站www.directui.com,做的很专业;另一家是UIEASY,网址www.uieasy.com,一个轻量级皮肤库DSkinLite。但是,网上关于DirectUI的技术文章却很少;早在 6/26/2005,一个国外的程序员就已经写了一个开源的DirectUI例子,应该算是国内所有directui界面库的起源了,网址http://www.viksoe.dk/code/windowless1.htm,探讨一种实现的可能性和思路,和实际应用虽有一定距离,不过却是一个很好的学习资料。再后来,一个国内的程序员“当个傻瓜蛋”,基于此代码,进行重构和修正Bug,并放到了google上开源,网址http://code.google.com/p/duilib/,下载地址svn checkout http://duilib.googlecode.com/svn/trunk/ duilib-read-only。
本人通过学习这个duilib的源代码,学到了很多知识、思路和经验,分享给看到此文的朋友,共同探讨DirectUI技术,并欢迎大家加入到开发开源DirectUI皮肤库的行列当中。分析难免有误,见谅!
一、核心类
- CWindowWnd,窗口对象管理父类,主要作用:
1) 创建窗口。
2) 窗口消息过程处理。
3) 提供窗口子类化与超类化接口。
- CDialogBuilder,控件布局类,主要作用:
1) 读取XML脚本,分析脚本,构建控件树。
2) 创建控件对象。
- CPaintManagerUI,窗口消息及图形绘制管理器类,与窗口绑定,主要作用:
1) 绘制控件。
2) 消息管理。
3) 事件通知。
- INotifyUI,事件通知抽象类,主要作用:
1) 重载Notify虚函数,处理事件通知。
二、控件类
- CControlUI,控件管理父类,主要作用:
1) 控件的通用基类,提供控件通用属性管理。
- CLabelUI,静态标签类,父类CControlUI。
- CButtonUI,按钮类,父类CLabelUI。
- COptionUI,选择按钮类,父类CButtonUI。
- CTextUI,静态文本类,父类CLabelUI。
- CProgressUI,进度条类,父类CLabelUI。
- CSliderUI,父类CProgressUI。
- CEditUI,编辑框类,父类CLabelUI。
- CListUI,列表框类,父类CVerticalLayoutUI、IListUI。
1) CListHeaderUI,父类CHorizontalLayoutUI。
2) CListHeaderItemUI,列表头类,父类CControlUI。
3) CListTextElementUI,类表文本类,父类CListLabelElementUI。
4) CListLabelElementUI,父类CListElementUI。
- CComboUI,组合框类,父类CContainerUI、IListOwnerUI。
- CActiveXUI,ActiveX控件类,父类CControlUI、 IMessageFilterUI。
- CContainerUI,容器类,父类CControlUI、IContainerUI。
- CTabLayoutUI,选项页布局类,父类CContainerUI。
- CTileLayoutUI,父类CContainerUI。
- CDialogLayoutUI,对话框布局类,父类CContainerUI。、
- CVerticalLayoutUI,垂直布局类,父类CContainerUI。
- CHorizontalLayoutUI,水平布局类,父类CContainerUI。
- CListExpandElementUI,父类CListTextElementUI。
- CListContainerElementUI,父类CContainerUI、IListItemUI。
三、辅助类
- CStdPtrArray,指针数组。
- CStdValArray,数据数组。
- CStdString,字符串数组。
- CStdStringPtrMap,字符串指针映射数组。
二、DUiLib 源码分析——第一篇UIManager
本篇分析一下源文件
UIManager.h/UIManager.cpp
CPaintManagerUI
成员变量
窗体句柄
o---m_hWndPaint 要CPaintManagerUI进行Direct绘图操作的窗体句柄
o---m_hwndTooltip 提示窗口句柄
o---m_hInstance 当前管理的Instance实例
o---m_hResourceInstance 当前管理的资源DLL Instance实例
o---m_pStrResourcePath 当前使用的资源路径
o---m_pStrResourceZip 当前使用的资源压缩包文件全称
------------------------------------------------------CPaintManagerUI使用的资源
绘图设备
o---m_hDcPaint 直接绘制到窗体的DC(为窗体的整个区域包括费客户区)
o---m_hDcOffscreen 内存缓冲区绘图DC
o---m_hDcBackground 背景绘制(支持AlphaBackground时使用)
位图
o---m_hbmpOffscreen m_hDcPaint的后台作图画布
o---m_hbmpBackground 背景图片bmp
------------------------------------------------------CPaintManagerUI用到的信息
o---m_ToolTip 提示消息
typedef struct tagTOOLINFOA {
UINT cbSize; //该结构体的大小 sizeof(TOOLINFO)
UINT uFlags; //附加标识类信息
HWND hwnd; //消息接受的窗体
UINT_PTR uId; //控件ID
RECT rect; //消息产生的区域位置
HINSTANCE hinst; //消息接收的实例
LPSTR lpszText; //提示消息
LPARAM lParam; //IE3.0以上的版本有该属性
void *lpReserved; //NT5.0以上的版本有该属性 附加信息
} TOOLINFO
标识类信息
o---m_bShowUpdateRect 是否显示更新区域
o---m_bFirstLayout 是否是首个布局
o---m_bUpdateNeeded 是否需要更新界面
o---m_bFocusNeeded 是否需要焦点
o---m_bOffscreenPaint 是否需要开双缓存绘图
o---m_bAlphaBackground 窗体背景是否需要支持Alpha通道(如png图片的半透明效果)
o---m_bMouseTracking 是否需要支持鼠标追踪
o---m_bMouseCapture 是否需要支持鼠标捕获
控件信息
o---m_pRoot xml根节点解析成的对象,通常为各种Window
o---m_pFocus 处于获得焦点状态的控件
o---m_pEventHover 处于鼠标悬停状态的控件
o---m_pEventClick 被鼠标点击的控件
o---m_pEventKey 接收键盘输入的控件
位置记录信息
o---m_pLastMousePos 鼠标最新的位置
o---m_szMinWindow 设置窗体可以调整到的最小大小
o---m_szMaxWindow 窗体可以调整到的最大大小
o---m_szInitWindowSize 窗体初始化是的大小
o---m_rcSizeBox 窗体外边框区域的大小
o---m_szRoundCorner 窗体四角的圆角弧度
o---m_rcCaption 窗体标题栏区域大小
o---m_uTimerID 当前定时器ID
集合类信息
o---m_aNotifiers 能够接收通知的对象集合
o---m_aTimers 定时器集合
o---m_aPreMessage 预处理消息集合
o---m_aPreMessageFilters 预处理消息过滤器集合
o---m_aMessageFilters 消息过滤器集合
o---m_aPostPaintControls 发送绘制请求的控件集合
o---m_aDelayedCleanup 延迟清理的对象集合
o---m_aAsyncNotify 异步通知消息集合
o---m_mNameHash 名称HashMap
o---m_mOptionGroup 选项组Map
xml对应资源
o---m_pParentResourcePM 上级(父类)资源的PaintManagerUI绘图管理器
o---m_dwDefaultDisabledColor 默认失效状态颜色
o---m_dwDefaultFontColor 默认字体颜色
o---m_dwDefaultLinkFontColor 默认超链接字体颜色
o---m_dwDefaultLinkHoverFontColor默认超链接鼠标悬停状态的字体颜色
o---m_dwDefaultSelectedBkColor 默认选中状态背景色
o---m_DefaultFontInfo 默认字体信息
TFontInfo{
hFont 该字体的句柄
sFontName 字体名称
iSize 字号
bBold 是否粗体
bUnderline 是否有下划线
bItalic 是否为斜体
TEXTMETRIC tm 该字体的TEXTMETRIC信息
}
o---m_aCustonFonts 自定义字体资源集合
o---m_mImageHash 图片资源HashMap
o---m_DefaultAttrHash DefaultAttr资源HashMap
私有方法
将所有的控件添加到m_mNameHash哈希表中
o---static CControlUI CALLBACK __FindControlFromNameHash(CControlUI pThis, LPVOID pData);
计算控件数量
o---static CControlUI CALLBACK __FindControlFromCount(CControlUI pThis, LPVOID pData);
根据点是否在区域中,查询控件
o---static CControlUI CALLBACK __FindControlFromPoint(CControlUI pThis, LPVOID pData);
通过Tab信息查询控件
o---static CControlUI CALLBACK __FindControlFromTab(CControlUI pThis, LPVOID pData);
从快照中查询控件
o---static CControlUI CALLBACK __FindControlFromShortcut(CControlUI pThis, LPVOID pData);
查找需要更新的控件
o---static CControlUI CALLBACK __FindControlFromUpdate(CControlUI pThis, LPVOID pData);
通过名称比较查询控件
o---static CControlUI CALLBACK __FindControlFromName(CControlUI pThis, LPVOID pData);
公开方法
绘图管理器的初始化(m_hWndPaint,m_hDcPaint赋值,在预处理消息中加入管理器)
+---void Init(HWND hWnd);
当前需要更新界面
+---void NeedUpdate();
指定区域失效
+---void Invalidate(RECT& rcItem);
获取绘图设备DC
+---HDC GetPaintDC() const;
获取绘图的窗口句柄
+---HWND GetPaintWindow() const;
获取提示窗体句柄
+---HWND GetTooltipWindow() const;
获取当前鼠标的位置
+---POINT GetMousePos() const;
获取客户区大小
+---SIZE GetClientSize() const;
获取窗体初始化时的大小
+---SIZE GetInitSize();
设置窗体初始化大小
+---void SetInitSize(int cx, int cy);
获取窗体的边框区域大小
+---RECT& GetSizeBox();
设置窗体的边框区域大小
+---void SetSizeBox(RECT& rcSizeBox);
获取标题区域位置
+---RECT& GetCaptionRect();
设置标题区域位置
+---void SetCaptionRect(RECT& rcCaption);
获取窗体四角的圆角弧度
+---SIZE GetRoundCorner() const;
设置窗体四角的圆角弧度
+---void SetRoundCorner(int cx, int cy);
获取窗体可以调整到的最小大小
+---SIZE GetMinInfo() const;
设置窗体可以调整到的最小大小
+---void SetMinInfo(int cx, int cy);
获取窗体可以调整到的最大大小
+---SIZE GetMaxInfo() const;
设置窗体可以调整到的最大大小
+---void SetMaxInfo(int cx, int cy);
窗体的不透明度(0完全透明-255完全不透明)
+---void SetTransparent(int nOpacity);
设置绘图是否支持透明处理
+---void SetBackgroundTransparent(bool bTrans);
是否显示更新区域
+---bool IsShowUpdateRect() const;
设置是否显示更新
+---void SetShowUpdateRect(bool show);
获取当前管理的实例句柄
+---static HINSTANCE GetInstance();
获得当前运行的实例的路径
+---static CStdString GetInstancePath();
获得当前的工作路径
+---static CStdString GetCurrentPath();
获取资源DLL的实例句柄
+---static HINSTANCE GetResourceDll();
获取资源的路径(以"\"结尾)
+---static const CStdString& GetResourcePath();
获得Zip资源的路径
+---static const CStdString& GetResourceZip();
设置实例句柄
+---static void SetInstance(HINSTANCE hInst);
设置当前的工作路径
+---static void SetCurrentPath(LPCTSTR pStrPath);
设置当前的DLL资源的实例句柄
+---static void SetResourceDll(HINSTANCE hInst);
设置资源所在文件夹路径
+---static void SetResourcePath(LPCTSTR pStrPath);
设置Zip资源的路径(包括Zip文件名)
+---static void SetResourceZip(LPCTSTR pStrZip);
设置使用上级资源的绘图管理器
+---bool UseParentResource(CPaintManagerUI pm);
获得上级资源绘图管理器
+---CPaintManagerUI GetParentResource() const;
获取禁用状态的默认颜色
+---DWORD GetDefaultDisabledColor() const;
设置禁用状态的默认颜色
+---void SetDefaultDisabledColor(DWORD dwColor);
获取字体默认颜色
+---DWORD GetDefaultFontColor() const;
设置字体默认颜色
+---void SetDefaultFontColor(DWORD dwColor);
设置链接文字的默认字体颜色
+---DWORD GetDefaultLinkFontColor() const;
获取链接文字的默认颜色
+---void SetDefaultLinkFontColor(DWORD dwColor);
获取鼠标悬停与超链上的默认字体颜色
+---DWORD GetDefaultLinkHoverFontColor() const;
获取鼠标悬停与超链上的默认字体颜色
+---void SetDefaultLinkHoverFontColor(DWORD dwColor);
获取选中状体的默认背景颜色
+---DWORD GetDefaultSelectedBkColor() const;
设置选中状态的默认背景颜色
+---void SetDefaultSelectedBkColor(DWORD dwColor);
获取默认使用的字体信息
+---TFontInfo GetDefaultFontInfo();
设置默认使用的字体信息
+---void SetDefaultFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
获取用户自定义字体的数量(一般对应xml中Font的数量)
+---DWORD GetCustomFontCount() const;
向字体数组列表追加字体资源
+---HFONT AddFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
向字体数组列表中插入字体资源
+---HFONT AddFontAt(int index, LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
获取数组中指定下标的字体对象句柄
+---HFONT GetFont(int index);
从字体数组中获取指定配置的字体对象句柄
+---HFONT GetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
字体数组集合中是否存在字体对象
+---bool FindFont(HFONT hFont);
字体数组集合中是否存在指定配置的字体对象
+---bool FindFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
获得字体对象的
+---int GetFontIndex(HFONT hFont);
根据指定的配置信息查询字体索引
+---int GetFontIndex(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
从字体数组列表中移除字体对象
+---bool RemoveFont(HFONT hFont);
从字体数组列表中移除指定位置的字体信息
+---bool RemoveFontAt(int index);
清空字体数组列表
+---void RemoveAllFonts();
通过字体数组索引查找字体信息
+---TFontInfo GetFontInfo(int index);
通过字体对象句柄获取字体信息
+---TFontInfo GetFontInfo(HFONT hFont);
根据图像路径查找图像信息
+---const TImageInfo GetImage(LPCTSTR bitmap);
根据名称,类型,遮罩色 查询 图像信息
+---const TImageInfo GetImageEx(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0);
添加图像
+---const TImageInfo AddImage(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0);
添加图像
+---const TImageInfo AddImage(LPCTSTR bitmap, HBITMAP hBitmap, int iWidth, int iHeight, bool bAlpha);
根据图像名称移除图像
+---bool RemoveImage(LPCTSTR bitmap);
移除全部图像
+---void RemoveAllImages();
添加控件的默认配置信息(如button)
+---void AddDefaultAttributeList(LPCTSTR pStrControlName, LPCTSTR pStrControlAttrList);
根据控件名称查询该类控件的默认配置
+---LPCTSTR GetDefaultAttributeList(LPCTSTR pStrControlName) const;
移除指定控件类型名称的默认配置
+---bool RemoveDefaultAttributeList(LPCTSTR pStrControlName);
获取默认配置信息列表
+---const CStdStringPtrMap& GetDefaultAttribultes() const;
清空默认配置信息列表
+---void RemoveAllDefaultAttributeList();
将对话框控件附加到当前的管理器中
+---bool AttachDialog(CControlUI pControl);
控件初始化
+---bool InitControls(CControlUI pControl, CControlUI pParent = NULL);
控件回收
+---void ReapObjects(CControlUI* pControl);
添加控件到指定的选项组
+---bool AddOptionGroup(LPCTSTR pStrGroupName, CControlUI pControl);
查询指定选项组名称中的全部选项
+---CStdPtrArray GetOptionGroup(LPCTSTR pStrGroupName);
从指定控件中移除指定选项组名称的选项组
+---void RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl);
清空全部选项组列表
+---void RemoveAllOptionGroups();
获取焦点状态的控件
+---CControlUI GetFocus() const;
设置控件为获得焦点状态
+---void SetFocus(CControlUI pControl);
设置控件为需要绘制焦点
+---void SetFocusNeeded(CControlUI* pControl);
设置下一个获得Tab键会获得焦点的控件,Tab是否继续往下走
+---bool SetNextTabControl(bool bForward = true);
为指定控件以及其子控件设置定时器
+---bool SetTimer(CControlUI pControl, UINT nTimerID, UINT uElapse);
移除指定控件上的指定编号的定时器
+---bool KillTimer(CControlUI pControl, UINT nTimerID);
清空所有的定时器
+---void RemoveAllTimers();
设置窗体接受鼠标事件
+---void SetCapture();
释放窗体捕获鼠标事件
+---void ReleaseCapture();
判断窗体是否接受鼠标事件
+---bool IsCaptured();
添加控件到通知集合中
+---bool AddNotifier(INotifyUI pControl);
将控件从通知集合中移除
+---bool RemoveNotifier(INotifyUI pControl);
发送同步/异步通知
+---void SendNotify(TNotifyUI& Msg, bool bAsync = false);
构建同步或异步通知并发送
+---void SendNotify(CControlUI* pControl, LPCTSTR pstrMessage, WPARAM wParam = 0, LPARAM lParam = 0, bool bAsync = false);
向预处理消息过滤器链中添加消息过滤器
+---bool AddPreMessageFilter(IMessageFilterUI pFilter);
从预处理消息过滤器链合中移除指定的消息过滤器
+---bool RemovePreMessageFilter(IMessageFilterUI pFilter);
向消息过滤器链中添加消息过滤器
+---bool AddMessageFilter(IMessageFilterUI pFilter);
从消息过滤器链中移除消息过滤器
+---bool RemoveMessageFilter(IMessageFilterUI pFilter);
获取发送需要绘制的控件的数量
+---int GetPostPaintCount() const;
向绘制请求集合中添加要绘制的控件
+---bool AddPostPaint(CControlUI pControl);
从绘制请求集合中移除指定的控件
+---bool RemovePostPaint(CControlUI pControl);
将绘制请求控件插入到绘制请求集合的指定位置
+---bool SetPostPaintIndex(CControlUI pControl, int iIndex);
向延迟清理集合中添加需要延迟清理的对象
+---void AddDelayedCleanup(CControlUI pControl);
获取根节点控件
+---CControlUI GetRoot() const;
从根节点开始查找指定点所在的控件
+---CControlUI FindControl(POINT pt) const;
从指定节点开始查找指定点所在的控件
+---CControlUI FindControl(CControlUI pParent, POINT pt) const;
从根节点开始,查找指定名称的控件
+---CControlUI FindControl(LPCTSTR pstrName);
从指定节点开始查找指定名称的控件
+---CControlUI FindControl(CControlUI* pParent, LPCTSTR pstrName);
消息循环,非游戏框架消息泵,无法利用无消息的空闲时间
+---static void MessageLoop();
消息翻译,在Win32原有的消息转换基础上,将需要自己处理的消息转发给消息预处理器
+---static bool TranslateMessage(const LPMSG pMsg);
消息预处理器
1.消息预处理过滤(消息预处理过滤器集合对消息进行过滤处理)
2.检查是否按下Tab键,设置下一个获得焦点的控件
3.处理Alt+Shortcut Key按下后的控件获得焦点和激活的设置
4.检查是否有系统键消息,有则发送获得焦点的控件的事件
+---bool PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
消息处理器(核心处理器)
1.消息过滤
2.检查Custom消息并处理
3.检查是否有WM_CLOSE消息并处理
4.处理WM_ERASEBKGND(不允许进行背景擦除,防止闪烁)
5.绘制处理(核心)
5.1做延迟绘图判断,当前是否有 窗体大小调整的操作,或者是否需要初始化窗体
5.2设置焦点控件
5.3如果开启双缓存绘图,采用双缓存方式绘图,否则采用标准绘图方式绘图
5.4
6.处理客户区的绘制WM_PRINTCLIENT
7.接到WM_GETMINMAXINFO消息后向系统提交该窗体可调整大小的最小和最大限制
8.窗体大小改变时,向焦点控件发送改变大小消息并设置窗体需要更新
9.处理定时器消息,向定时器集合中广播定时消息
10.处理鼠标悬停
10.1向鼠标悬停的控件发送鼠标悬停消息
10.2如果当前控件有提示消息,创建消息提示窗体
11.处理鼠标离开事件,关闭消息提示框,发送鼠标离开消息,取消鼠标的追踪
12.鼠标移动时,开始追踪鼠标
12.1处理鼠标移动时,鼠标在控件上进入,移动,悬停和离开的消息
13.处理鼠标左键按下的消息设定活动的焦点的控件
14.鼠标双击事件处理,向需要接收鼠标双击事件的控件发送双击事件
15.鼠标左键抬起时,向上次接收到点击消息的控件发送鼠标左键抬起的消息
16.鼠标右键按下时,向需要接收鼠标右键按下的控件发送右键按下消息
17.鼠标右键快捷菜单消息,将该消息通知给上次点击过的按钮
18.滚轮消息时,象鼠标所在的控件发送滚轮消息
19.WM_CHAR 消息时,向获得焦点的控件发送该消息
20.键盘按下时,向焦点控件发送该键盘消息,并设定焦点控件为键盘消息控件
21.键盘按键抬起时,向事键盘消息控件发送该事件
22.设定鼠标光标消息时,获得光标所在控件接收该消息
23.通知消息到来时,加OCM_BASE后发送通知消息
24.命令消息到来,加OCM_BASE后发送消息
25.WM_CTLCOLOREDIT,STATIC消息到来后,加OCM_BASE后发送消息
+---bool MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
三、DUiLib 源码分析——第二篇UIBase
本篇分析一下源文件
UIBase.h/UIBase.cpp
UILib的基础类的定义源文件
包括UI中常用宏的封装、代码调试宏、
绘图常用的各种数据结构,以及UILib中的窗体类等
UI里的宏
窗体样式宏
+---UI_WNDSTYLE_CONTAINER 容器样式,无任何样式
+---UI_WNDSTYLE_FRAME UI标准框架窗体样式(标题栏、边框、图标、标题、最大、最小按钮、关闭按钮)
+---UI_WNDSTYLE_CHILD UI窗体子控件样式
+---UI_WNDSTYLE_DIALOG UI对话框窗体样式
扩展窗体样式宏
+---UI_WNDSTYLE_EX_FRAME 窗体客户区凹陷样式
+---UI_WNDSTYLE_EX_DIALOG 工具栏窗口样式+模式对话框样式
类样式宏
+---UI_CLASSSTYLE_CONTAINER 类容器样式
+---UI_CLASSSTYLE_FRAME 水平、垂直大小改变时绘制
+---UI_CLASSSTYLE_CHILD 水平、垂直大小改变时绘制、支持双击事件、保存窗体位图
+---UI_CLASSSTYLE_DIALOG 水平、垂直大小改变时绘制、支持双击事件、保存窗体位图
ASSERT(expr) 判断表达式是否为NULL或FALSE
TRACE(LPSTSTR pstrFormat,...)
在Debug输出窗口打印格式化字符串
TRACEMSG(UINT uMsg) 返回指定消息的16进制表示
基础类
STRINGorID 用于构建资源名称或资源ID号
x---LPCTSTR m_lpstr;
+---STRINGorID(LPCTSTR lpString)
+---STRINGorID(UINT nID)
CPoint 点的封装类,支持LPARAM构建点
+---CPoint();
+---CPoint(const POINT& src);
+---CPoint(int x, int y);
+---CPoint(LPARAM lParam);
CSize 大小封装
+---CSize();
+---CSize(const SIZE& src);
+---CSize(const RECT rc);
+---CSize(int cx, int cy);
CRect 区域封装
+---CRect();
+---CRect(const RECT& src);
+---CRect(int iLeft, int iTop, int iRight, int iBottom);
+---int GetWidth() const 获取宽度
+---int GetHeight() const 获取高度
+---void Empty() 清空
+---bool IsNull() const 是否为Empty,IsEmpty
+---Join(const RECT& rc) 支持区域合并
+---Normalize() 正规化(使得left<right,top<bottom)
+---Offset(int cx, int cy) 区域偏移(移动)操作
+---Inflate(int cx, int cy) 区域膨胀
+---Deflate(int cx, int cy) 区域收缩
+---Union(CRect& rc) 区域并操作
CStdPtrArray 指针数组类
x---LPVOID* m_ppVoid 数据指针
x---int m_nCount 指针数量
x---int m_nAllocated 内存已分配大小
+---void Empty() 清空记录
+---void Resize(int iSize) 重新分配内存大小(注意:之前的记录丢失)
+---bool IsEmpty() const 是否为空数组
+---int Find(LPVOID iIndex) const 查询指定元素的索引号
+---bool Add(LPVOID pData) 在指针集合中添加新数据
+---bool SetAt(int iIndex, LPVOID pData)设置指定索引号处的新数据
+---bool InsertAt(int iIndex, LPVOID pData)在指定的索引号处插入数据
+---bool Remove(int iIndex) 移除指定索引号得数据
+---int GetSize() const 获取指针数量
+---LPVOID* GetData() 获取全部的数据
+---LPVOID GetAt(int iIndex) const 查询索引号所对应的元素
+---LPVOID operator[] (int nIndex) const支持[]查找元素
CStdValArray 自定义数据长度数组类
x---LPBYTE m_pVoid 指针数据
x---int m_iElementSize 元素大小
x---int m_nCount 元素数量
x---int m_nAllocated 当前分配的可用容量
+---CStdValArray(int iElementSize, int iPreallocSize = 0)
指定元素大小,预分配数量
+---void Empty() 清空数据
+---bool IsEmpty() const 是否为空数组
+---bool Add(LPCVOID pData) 追加数据
+---bool Remove(int iIndex) 移除指定索引号得数据
+---int GetSize() const 获取当前保存元素的个数
+---LPVOID GetData() 获取数据
+---LPVOID GetAt(int iIndex) const 获取指定索引号处的数据
+---LPVOID operator[] (int nIndex) const支持[]查找元素
CStdString 字符串类
x---LPTSTR m_pstr; 字符指针
x---TCHAR m_szBuffer[MAX_LOCAL_STRING_LEN + 1];字符缓冲区
+---CStdString(); 初始化字符串类
+---CStdString(const TCHAR ch);
+---CStdString(const CStdString& src);
+---CStdString(LPCTSTR lpsz, int nLen = -1);长度为-1由程序自己判断长度
+---void Empty(); 清空字符串
+---int GetLength() const; 获取字符串长度
+---bool IsEmpty() const; 字符串是否为空串
+---TCHAR GetAt(int nIndex) const; 获取指定位置处的字符
+---void Append(LPCTSTR pstr); 字符串追加操作
+---void Assign(LPCTSTR pstr, int nLength = -1);分配内存赋值
+---LPCTSTR GetData(); 获取字符串指针
+---void SetAt(int nIndex, TCHAR ch); 在指定索引处设置字符
+---int Compare(LPCTSTR pstr) const; 字符串比较
+---int CompareNoCase(LPCTSTR pstr) const;字符串忽略大小写比较
+---void MakeUpper(); 字符串转换为大小
+---void MakeLower(); 字符串转换为小写
+---CStdString Left(int nLength) const; 从左边截取指定长度的子串
+---CStdString Mid(int iPos, int nLength = -1) const;
截取中间字符串
+---CStdString Right(int nLength) const;从右开始截取指定长度的字符串
+---int Find(TCHAR ch, int iPos = 0) const;
从指定位置开始寻找匹配字符的位置
+---int Find(LPCTSTR pstr, int iPos = 0) const;
重指定位置开始寻找匹配字符串的位置
+---int ReverseFind(TCHAR ch) const; 反向查询字符位置
+---int Replace(LPCTSTR pstrFrom, LPCTSTR pstrTo);
将匹配的字符子串用指定字符串替换
+---int __cdecl Format(LPCTSTR pstrFormat, ...);
最长63位的字符串格式化
+---int __cdecl SmallFormat(LPCTSTR pstrFormat, ...);
一次格式化1024长度的字符串格式化
TITEM结构
o---CStdString Key 键
o---LPVOID Data 值
o---struct TITEM* pNext 下一个TITEM结构体指针
CStdStringPtrMap
x---TITEM** m_aT; TITEM双指针
x---int m_nBuckets; 容器容量
+---CStdStringPtrMap(int nSize = 83); 构建字符串Map集合
+---void Resize(int nSize = 83); 重新分配集合大小
+---LPVOID Find(LPCTSTR key) const; 更具键查询字符串指针
+---bool Insert(LPCTSTR key, LPVOID pData);插入数据
+---LPVOID Set(LPCTSTR key, LPVOID pData);设置指定键的数据
+---bool Remove(LPCTSTR key); 通过键移除数据
+---int GetSize() const; 获取大小
+---LPCTSTR GetAt(int iIndex) const; 获取指定索引处得字符串
+---LPCTSTR operator[] (int nIndex) const;通过下标获取字符串
CWindowWnd
x---HWND m_hWnd 窗体句柄,初始化为NULL
x---WNDPROC m_OldWndProc Win32窗口过程,默认为DefWindowProc
x---bool m_bSubclassed 是否子类化,默认为false
获取窗口类名称,子类必须实现该纯虚函数
o---virtual LPCTSTR GetWindowClassName() const = 0;
获取父类名称,用以子类化
o---virtual LPCTSTR GetSuperClassName() const;
获得类样式
o---virtual UINT GetClassStyle() const;
消息处理函数
o---virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
窗体销毁前最后的处理工作
o---virtual void OnFinalMessage(HWND hWnd);
窗口过程回调函数
o---static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
控件过程回调函数
o---static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
---------------------------------------------------------------------
+---CWindowWnd();
获取窗口句柄
+---HWND GetHWND() const;
获取窗口句柄
+---operator HWND() const;
注册窗口过程
1.调用GetClassStyle获取样式信息
2.调用绘图管理器的静态函数获取实例CPaintManagerUI::GetInstance()
3.调用GetWindowClassName()获取要注册的类名称
+---bool RegisterWindowClass();
通过已存在的窗体作为父类注册窗口类
+---bool RegisterSuperclass();
窗口创建
+---HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
创建窗口
1.如果存在父类名,就用注册父类来创建
2.不存在父类名,进行正常的窗口注册
3.以上注册成功后,创建窗口
+---HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
窗口子类化
+---HWND Subclass(HWND hWnd);
卸载窗口子类化
+---void Unsubclass();
显示窗口
+---void ShowWindow(bool bShow = true, bool bTakeFocus = true);
显示模式窗口
+---bool ShowModal();
关闭窗口
+---void Close();
窗口居中,如果为子窗口,则居于父窗口的中央
+---void CenterWindow();
通过资源ID号设置图标
+---void SetIcon(UINT nRes);
发送UI同步消息
+---LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
投递UI异步消息
+---LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
调整客户区大小
+---void ResizeClient(int cx = -1, int cy = -1);
CWaitCursor 等待光标
x---HCURSOR m_hOrigCursor 替换前光标
+---CWaitCursor() 设置成等待光标
+---~CWaitCursor() 还原为之前的光标
四、DUILibxml配置
DUILibxml配置项 根节点 子类 属性 类型 Window |
--------Image 图片信息 | o------name string | o------restype string | o------mask unsigned long# |
---|---|---|---|---|
--------Font 字体信息 | ||||
o------name string | ||||
o------size long | ||||
o------bold bool | ||||
o------underline bool | ||||
o------default bool | ||||
--------Default 默认Attribute属性 |
o------name string
o------value string
root(Window属性)
o--size 窗体初始化大小 SIZE(int cx, int cy)
o--sizebox 窗体区域 RECT(long left, long top, long right,long bottom)
o--caption 窗体标题栏区域 RECT(long left, long top, long right,long bottom)
o--roundcorner 圆角大小 SIZE(int cx, int cy)
o--mininfo 窗体最小大小 SIZE(int cx, int cy)
o--maxinfo 窗体最大大小 SIZE(int cx, int cy)
o--showdirty 窗体显示 bool [true|false]
o--alpha 窗体透明度 int
o--bktrans 背景是否支持透明 bool [true|false]
o--disabledfontcolor 无效字体颜色 string #RRGGBBAA
o--defaultfontcolor 默认字体颜色 string #RRGGBBAA
o--linkfontcolor 链接正常字体色 string #RRGGBBAA
o--linkhoverfontcolor链接悬停字体色 string #RRGGBBAA
o--selectedcolor 字体被选后颜色 string #RRGGBBAA
公共资源
Image
|------o file/res string
|------o restype string
|------o dest RECT(long left, long top, long right,long bottom)
|------o source RECT(long left, long top, long right,long bottom)
|------o corner RECT(long left, long top, long right,long bottom)
|------o mask string #FFFFFFFF
|------o fade byte
|------o hole bool [true|false]
|------o xtiled bool [true|false]
|------o ytiled bool [true|false]
使用说明:
// 1、aaa.jpg
// 2、file=‘aaa.jpg‘ res=‘‘ restype=‘0‘ dest=‘0,0,0,0‘ source=‘0,0,0,0‘ corner=‘0,0,0,0‘
// mask=‘#FF0000‘ fade=‘255‘ hole=‘false‘ xtiled=‘false‘ ytiled=‘false‘
Font
Default
控件Control
控件名称 类
控件基类
Control CControlUI
|------o pos RECT(long left, long top, long right,long bottom)
|------o relativepos (int nMoveXPercent, int nMoveYPercent,int nZoomXPercent,int nZoomYPercent)
|------o padding RECT(long left, long top, long right,long bottom)
|------o bkcolor/bkcolor1 string #RRGGBBAA
|------o bkcolor2 string #RRGGBBAA
|------o bkcolor3 string #RRGGBBAA
|------o bordercolor string #RRGGBBAA
|------o focusbordercolor string #RRGGBBAA
|------o bordersize int
|------o borderround SIZE(int x, int y)
|------o bkimage Image 属性
|------o width int
|------o height int
|------o minwidth int
|------o minheight int
|------o maxwidth int
|------o maxheight int
|------o name string
|------o text string
|------o tooltip string
|------o userdata string
|------o enabled bool [true|false]
|------o mouse bool [true|false]
|------o visible bool [true|false]
|------o float bool [true|false]
|------o shortcut TCHAR
|------o menu bool [true|false]
容器
Container CContainerUI
|------o inset RECT(long left, long top, long right,long bottom)
|------o mousechild bool [true|false]
|------o vscrollbar bool [true|false]
|------o hscrollbar bool [true|false]
|------o childpadding int
布局管理器
VerticalLayout CVerticalLayoutUI : public CContainerUI
|------o sepheight int
|------o sepimm bool [true|false]
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
HorizontalLayout CHorizontalLayoutUI : public CContainerUI
|------o sepwidth int
|------o sepimm bool [true|false]
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
DialogLayout CDialogLayoutUI : public CContainerUI
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
TileLayout CTitleLayoutUI : public CContainerUI
|------o columns int
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
TabLayout CTabLayoutUI : public CContainerUI
|------o selectedid int
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
Edit CEditUI : public CLabelUI
|------o readonly bool [true|false]
|------o password bool [true|false]
|------o maxchar int
|------o normalimage Image 属性
|------o hotimage Image 属性
|------o focusedimage Image 属性
|------o disabledimage Image 属性
|------o nativebkcolor string #RRGGBBAA
|------o CLabelUI::SetAttribute(pstrName, pstrValue)
List CListUI : public CVerticalLayoutUI, public IListUI
|------o header string bool [hidden|Show]
|------o headerbkimage string path
|------o scrollselect bool [true|false]
|------o multiexpanding bool [true|false]
|------o itemfont int Font列表的索引号
|------o itemalign string enum [left|center|right]
|------o itemendellipsis bool [true|false]
|------o itemtextpadding RECT(long left, long top, long right,long bottom)
|------o itemtextcolor string #RRGGBBAA
|------o itembkcolor string #RRGGBBAA
|------o itemimage string path
|------o itemselectedtextcolor string #RRGGBBAA
|------o itemselectedbkcolor string #RRGGBBAA
|------o itemselectedimage string path
|------o itemhottextcolor string #RRGGBBAA
|------o itemhotbkcolor string #RRGGBBAA
|------o itemhotimage Image 属性
| |------o file string path
| |------o corner RECT(long left, long top, long right,long bottom)
|------o itemdisabledtextcolor string #RRGGBBAA
|------o itemdisabledbkcolor string #RRGGBBAA
|------o itemdisabledimage Image 属性
|------o itemlinecolor string #RRGGBBAA
|------o itemshowhtml bool [true|false]
|------o CVerticalLayoutUI::SetAttribute(pstrName, pstrValue)
ListHeaderItem CListHeaderItemUI : public CControlUI
|------o dragable bool [true|false]
|------o sepwidth int
|------o align string enum [left|center|right]
|------o itemshowhtml bool [true|false]
|------o endellipsis bool [true|false]
|------o font int Font列表的索引号
|------o textcolor string #RRGGBBAA
|------o textpadding RECT(long left, long top, long right,long bottom)
|------o showhtml bool [true|false]
|------o normalimage Image 属性
|------o hotimage Image 属性
|------o pushedimage Image 属性
|------o focusedimage Image 属性
|------o sepimage Image 属性
CListElementUI : public CControlUI, public IListItemUI
|------o selected value 有此属性就选中
|------o CControlUI::SetAttribute(pstrName, pstrValue)
ListExpandElement CListExpandElementUI : public CListTextElementUI
|------o expander RECT(long left, long top, long right,long bottom)
|------o hideself bool [true|false]
|------o selected bool
|------o CListTextElementUI::SetAttribute(pstrName, pstrValue)
ListContainerElement CListContainerElementUI List容器
|------o selected value 有此属性就选中
ListHeader CListHeaderUI
CListLabelElementUI : public CListElementUI
ListTextElement CListTextElementUI : public CListLabelElementUI
Label CLabelUI : public CControlUI
|------o align string enum [left|center|right]
|------o endellipsis bool [true|false]
|------o font int Font列表的索引号
|------o textcolor string #RRGGBBAA
|------o disabledtextcolor string #RRGGBBAA
|------o textpadding RECT(long left, long top, long right,long bottom)
|------o showhtml bool [true|false]
|------o CControlUI::SetAttribute( pstrName, pstrValue )
Text CTextUI : public CLabelUI
Combo CComboUI : public CContainerUI, public IListOwnerUI
|------o textpadding RECT(long left, long top, long right,long bottom)
|------o normalimage Image 属性
|------o hotimage Image 属性
|------o pushedimage Image 属性
|------o focusedimage Image 属性
|------o disabledimage Image 属性
|------o dropbox string
|------o itemfont int Font列表的索引号
|------o itemalign string enum [left|center|right]
|------o itemtextpadding RECT(long left, long top, long right,long bottom)
|------o itemtextcolor string #RRGGBBAA
|------o itembkcolor string #RRGGBBAA
|------o itemimage Image 属性
|------o itemselectedtextcolor string #RRGGBBAA
|------o itemselectedimage Image 属性
|------o itemhottextcolor string #RRGGBBAA
|------o itemhotbkcolor string #RRGGBBAA
|------o itemhotimage Image 属性
|------o itemdisabledtextcolor string #RRGGBBAA
|------o itemdisabledbkcolor string #RRGGBBAA
|------o itemdisabledimage Image 属性
|------o itemlinecolor string #RRGGBBAA
|------o itemshowhtml bool [true|false]
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
Button CButtonUI : public CLabelUI
|------o normalimage Image 属性
|------o hotimage Image 属性
|------o pushedimage Image 属性
|------o focusedimage Image 属性
|------o disabledimage Image 属性
|------o hottextcolor string #RRGGBBAA
|------o pushedtextcolor string #RRGGBBAA
|------o focusedtextcolor string #RRGGBBAA
|------o CLabelUI::SetAttribute(pstrName, pstrValue)
Option COptionUI : public CButtonUI
|------o group string
|------o selected bool [true|false]
|------o selectedimage Image 属性
|------o foreimage Image 属性
|------o selectedtextcolor string #RRGGBBAA
|------o CButtonUI::SetAttribute(pstrName, pstrValue)
Progress CProgressUI : public CLabelUI
|------o fgimage Image 属性
|------o hor bool
|------o min int
|------o max int
|------o value int
|------o CLabelUI::SetAttribute(pstrName, pstrValue)
Slider CSliderUI : public CProgressUI
|------o thumbimage Image 属性
|------o thumbhotimage Image 属性
|------o thumbpushedimage Image 属性
|------o thumbsize SIZE(int x, int y)
|------o step int
|------o CProgressUI::SetAttribute(pstrName, pstrValue)
RichEdit CRichEditUI : public CContainerUI, public IMessageFilterUI
|------o vscrollbar bool [true|false]
|------o autovscroll bool [true|false]
|------o hscrollbar bool [true|false]
|------o autohscroll bool [true|false]
|------o wanttab bool [true|false]
|------o wantreturn bool [true|false]
|------o wantctrlreturn bool [true|false]
|------o rich bool [true|false]
|------o multiline bool [false|true]
|------o readonly bool [true|false]
|------o numberonly bool [true|false]
|------o password bool [true|false]
|------o align string enum [left|center|right]
|------o font int Font列表的索引号
|------o textcolor string #RRGGBBAA
|------o CContainerUI::SetAttribute(pstrName, pstrValue)
ActiveX CActiveXUI : public CControlUI
|------o clsid string
|------o modulename string
|------o delaycreate bool [true|false]
|------o CControlUI::SetAttribute(pstrName, pstrValue)
ScrollBar CScrollBarUI : public CControlUI
|------o button1normalimage Image 属性
|------o button1hotimage Image 属性
|------o button1pushedimage Image 属性
|------o button1disabledimage Image 属性
|------o button2normalimage Image 属性
|------o button2hotimage Image 属性
|------o button2pushedimage Image 属性
|------o button2disabledimage Image 属性
|------o thumbnormalimage Image 属性
|------o thumbhotimage Image 属性
|------o thumbpushedimage Image 属性
|------o thumbdisabledimage Image 属性
|------o railnormalimage Image 属性
|------o railhotimage Image 属性
|------o railpushedimage Image 属性
|------o raildisabledimage Image 属性
|------o bknormalimage Image 属性
|------o bkhotimage Image 属性
|------o bkpushedimage Image 属性
|------o bkdisabledimage Image 属性
|------o hor bool [true|false]
|------o linesize int
|------o range int
|------o value int
|------o showbutton1 bool [true|false]
|------o showbutton2 bool [true|false]
|------o CControlUI::SetAttribute(pstrName, pstrValue)
控件的通用属性
stretch STRETCHMODE
o--------move_x
o--------move_y
o--------move_xy
o--------size_x
o--------size_y
o--------size_xy
o--------group
o--------line
考虑到在xml编辑器中使用<>符号不方便,可以使用{}符号代替
支持标签嵌套(如<l><b>text</b></l>),但是交叉嵌套是应该避免的(如<l><b>text</l></b>)
The string formatter supports a kind of "mini-html" that consists of various short tags:
Bold: <b>text</b>
Color: <c #xxxxxx>text</c> where x = RGB in hex
Font: <f x>text</f> where x = font id
Italic: <i>text</i>
Image: <i x y z> where x = image name and y = imagelist num and z(optional) = imagelist id
Link: <a x>text</a> where x(optional) = link content, normal like app:notepad or http:www.xxx.com
NewLine <n>
Paragraph: <p x>text</p> where x = extra pixels indent in p
Raw Text: <r>text</r>
Selected: <s>text</s>
Underline: <u>text</u>
X Indent: <x i> where i = hor indent in pixels
Y Indent: <y i> where i = ver indent in pixels
五、duilib库分析: 消息流程分析
看下CWindowWnd类与CPaintManagerUI类是咋进行消息分发的吧.
- 先看下CPaintManagerUI类的MessageLoop函数:
void CPaintManagerUI::MessageLoop()
{
MSG msg = { 0 };
while( ::GetMessage(&msg, NULL, 0, 0) ) {
if( !CPaintManagerUI::TranslateMessage(&msg) ) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
消息第一次会由CPaintManagerUI类的TranslateMessage消息接收到.
- 调用CWindowWnd::Create创建窗口. 完成以下操作:
1) 如果要子类下Window的控件(就是系统的控件, 而不是duilib的模拟控件), 就设置__ControlProc函数为消息回调函数.
2)不子类化, 就注册窗口类. 此时设置__WndProc为窗口消息处理回调函数.
3)用CreateWindowEx API函数创建窗口.
这里先不看子类化相关的, 我要先看明白标准的窗口创建过程. 这也操作后消息就会分发到__WndProc了,
- 看下__WndProc函数的定义:
LRESULT CALLBACK CWindowWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindowWnd pThis = NULL;
if( uMsg == WM_NCCREATE ) {
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
pThis = static_cast<CWindowWnd>(lpcs->lpCreateParams);
pThis->m_hWnd = hWnd;
::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis));
}
else {
pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
if( uMsg == WM_NCDESTROY && pThis != NULL ) {
LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
if( pThis->m_bSubclassed ) pThis->Unsubclass();
pThis->m_hWnd = NULL;
pThis->OnFinalMessage(hWnd);
return lRes;
}
}
if( pThis != NULL ) {
return pThis->HandleMessage(uMsg, wParam, lParam);
}
else {
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
消息第二次就由WndProc接收到, 然后再传到CWindowWnd类的HandlerMessage函数中.
- 看看CWindowWnd类的继承类对于HandlerMessage虚函数的实现.
LRESULT CMainWnd::HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
LRESULT lRes = 0;
BOOL bHandled = TRUE;
switch ( uMsg )
{
case WM_CREATE: lRes = OnInitResource( bHandled ); break;
default:
bHandled = FALSE;
}
if ( bHandled )
{
return lRes;
}
if ( m_pm.MessageHandler( uMsg, wParam, lParam, lRes ) )
{
return lRes;
}
return CWindowWnd::HandleMessage( uMsg, wParam, lParam );
}
在这里就是用户要按消息进行具体的处理了. 之后要传到CPaintManagerUI类对象的MessageHandler函数. 未处理的消息就要返回给CWindowWnd类的默认消息处理函数来处理了.
- CPaintManagerUI类的TranslateMessage, MessageHandler函数的内容.
BOOL CPaintManagerUI::TranslateMessage(const LPMSG pMsg)
{
HWND hwndParent = ::GetParent(pMsg->hwnd);
UINT uStyle = GetWindowStyle(pMsg->hwnd);
LRESULT lRes = 0;
for( int i = 0; i < m_aPreMessages.GetSize(); i++ ) {
CPaintManagerUI pT = static_cast<CPaintManagerUI>(m_aPreMessages[i]);
if( pMsg->hwnd == pT->GetPaintWindow()
|| (hwndParent == pT->GetPaintWindow() && ((uStyle & WS_CHILD) != 0)) )
{
if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) return TRUE;
}
}
return FALSE;
}
m_aPreMessage为静态成员变量, 在CPaintManagerUI::Init进行窗口与此类绑定时添加到此变量中.
- CPaintManagerUI::PreMessageHandler消息过滤函数.
BOOL CPaintManagerUI::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& )
{
for( int i = 0; i < m_aPreMessageFilters.GetSize(); i++ )
{
BOOL bHandled = FALSE;
LRESULT lResult = static_cast<IMessageFilterUI*>(m_aPreMessageFilters[i])->MessageHandler(uMsg, wParam, lParam, bHandled);
if( bHandled ) {
return TRUE;
}
}
}
- CPaintManagerUI::MessageHandler函数.
1) 遍历m_aMessageFilters列表中的IMessageFilterUI接口, 并调用MessageHandler函数, 再次进行相关的消息过滤功能.(与上面的m_aPreMessageFilters类似)
2) 在此会处理窗口的WM_PAINT消息. 显示所有控件的外观与状态.
3) 处理鼠标事件, 实现控件激活和相关事件.
4) 处理WM_TIMER消息, 所有控件要用CPaintManagerUI的SetTimer, KillTimer等函数实现计时器功能.
5) 处理CPaintManagerUI类的自定消息, WM_APP + 1与 +2,
WM_APP + 1是用于控件延迟销毁控件对象
WM_APP + 2销毁异步消息的处理.
( 异步控件消息用CPaintManagerUI::SendNotify函数, 把消息对象添加到m_aAsyncNotify列表中, 再PostMessage函数WM_APP + 2 )
5) 其它基本的窗口相关消息的处理.
CPaintManagerUI把DUILIB内部的事件都是用TEventUI结构的形式调用CControlUI类的Event函数来投递的.
原文地址:http://blog.51cto.com/10978452/2109296