程序与技术分享:DirectUI的初步分析

简介: 程序与技术分享:DirectUI的初步分析

一、核心


1 、CWindowWnd: 窗口对象类(窗口实例对象父类)


2 、CDialogBuilder: 创建控件类,分析脚本并用递归方式(_Parse函数)创建所有控件实例


3 、CPaintManagerUI: 窗口消息及图形绘制管理器类


4 、CGUIRenderEngineUI: 图形渲染引擎类,在离屏DC中生成最终显示的图形,可根据需要扩展多种图形效果显示。


5 、INotifyUI: 事件通知抽象类


6 、IMessageFilterUI: 消息过滤抽象类


二、控件


CControlUI: 控件管理抽象父类,父类INotifyUI


1 、button


CButtonUI: 按钮控件


COptionUI: 选择按钮控件


2 、combox


CSingleLinePickUI:


CDropDownUI: 下拉控件,父类另有CContainerUI和IListOwnerUI


3 、decoration


CTitleShadowUI: 阴影效果


CListHeaderShadowUI


CSeparatorLineUI


CFadedLineUI


4 、edit


CSingleLineEditUI: 单行编辑框控件


CMultiLineEditUI: 多行编辑框控件


5 、label


CLabelPanelUI: 可设置背景色和文字色的静态标签控件


CGreyTextHeaderUI


6 、list


//代码效果参考: http://www.jhylw.com.cn/301634807.html

第一种:


CListUI: 列表控件,包含以下几个子控件


( 1 )CListHeaderItemUI: 列表头


( 2 )CListExpandElementUI: 列表项


第二种:用法不明


CListHeaderUI: 列表头


CListElementUI: 列表项,父类另有IListItemUI


CListLabelElementUI: 列表项,父类CListElementUI


CListTextElementUI: 列表项


CListFooterUI: 列表尾


7 、panel


CTextPanelUI: 父类CLabelPanelUI


CTaskPanelUI:


CNavigatorPanelUI: 导航面板,父类另有IListOwnerUI,包含CNavigatorButtonUI子控件


CSearchTitlePanelUI:


CImagePanelUI: 图片显示


CWarningPanelUI: 警告提示,父类CTextPanelUI


CPaddingPanelUI: 填充栏


8 、tab


CTabFolderUI: 父类另有CContainerUI和IListOwnerUI


CTabPageUI: 父类另有CContainerUI


9 、toolbar


CToolbarUI: 工具栏,包含以下几个子控件


( 1 )CToolButtonUI: 图形按钮


( 2 )CToolSeparatorUI: 分隔符


( 3 )CToolGripperUI: gripper


10 、title


CToolbarTitlePanelUI:


11 、statusbar


CStatusbarUI: 状态栏,父类另有CContainerUI


12 、anim


CAnimJobUI: 动画显示类


13 、ActiveX


CActiveXUI:


三、容器:


CContainerUI: 容器类,父类CControlUI和IContainerUI。可以认为容器是特殊的控件(见上面控件类关于父类的说明),其目的之一是具有容器特性的控件可以容纳其它控件,这样可以方便的实现控件的叠加;目的之二实际的窗口只有一个,对于叠加的控件必须要进行层次管理才能正确绘图和事件分发。另外可参见引用三


1 、画布: CCanvasUI(父类CContainerUI),可绘制背景色、画线、贴图


CWindowCanvasUI: 父类CCanvasUI


CControlCanvasUI: 父类CCanvasUI


CWhiteCanvasUI: 父类CCanvasUI


CDialogCanvasUI: 父类CCanvasUI


CTabFolderCanvasUI: 父类CCanvasUI


2 、布局: 管理不同层次的控件


CDialogLayoutUI: 父类CContainerUI


CVerticalLayoutUI: 父类CContainerUI


CHorizontalLayoutUI: 父类CContainerUI


CTileLayoutUI: 父类CContainerUI


四、通用


1 、script


CMarkup


CMarkupNode


2 、language


CUIUtility


3 、multi - thread


CriticalSection


AutoCriticalSection


CMutex


CAutoMutex


CEvent


CAutoEvent


CManualEvent


五、主要数据成员


1 、CPaintManagerUI


CControlUI m_pRoot: 如果控件是叠加的则存放最下层的控件对象,否则存放第一个创建的控件对象


CControlUI m_pFocus: 存放获得焦点的控件对象指针


CControlUI m_pEventHover: 存放当前有鼠标移进移出事件的控件对象指针


CControlUI m_pEventClick: 存放当前有点击事件的控件对象指针


CControlUI m_pEventKey: 存放当前有按键事件的控件对象指针


CStdPtrArray m_aNotifiers: 记录所有需要事件通知的窗口,根据窗口名称调用相应的消息处理函数


CStdPtrArray m_aNameHash: 保存控件对象指针hash表(用控件名称生成hash值)


CStdPtrArray m_aPostPaint: panel的fade效果


CStdPtrArray m_aMessageFilters: 保存需要进行消息过滤的控件或功能(如动画类)


CStdPtrArray m_aDelayedCleanup:


CStdPtrArray m_aPreMessages: 预处理消息


HWND m_hWndPaint: 控件布局窗口句柄


HDC m_hDcPaint: 控件布局窗口设备DC


HDC m_hDcOffscreen: 离屏内存DC


HBITMAP m_hbmpOffscreen: 离屏内存DC相关联HBITMAP


2 、CControlUI


CPaintManagerUI m_pManager: 窗口或控件绘图及消息管理器


CControlUI * m_pParent: 逻辑上的父窗口(控件)对象指针


CStdString m_sName: 控件标识


CStdString m_sText: 控件显示标题或显示脚本字符串


CStdString m_sToolTip: 控制的Tip信息


3 、CContainerUI


CStdPtrArray m_items: 同一层的控件对象或控件对象的子对象,例如canvas上放置的按钮、combox由edit和list两个子对象组成,其它还有tab等。具体见CDropDownUI、CTabFolderUI、CNavigatorPanelUI三个类定义


4 、CDialogLayoutUI


CStdValArray m_aModes: 用于存放在Layout上绝对坐标转成相对坐标(CDialogLayoutUI::RecalcArea)的控件对象(指针、大小、模式),目的是否为了让布局上的控件随布局变化而变化,能够正确绘图???


六、控件属性


待完成


七、脚本例子


[/span> Dialog

[/span> WindowCanvas pos = \ " 0,0,600,800\ "

[/span> DialogLayout pos = \ " 0,0,600,800\ "

[/span> Button pos = \ " 390, 30, 490, 58\ " text = \ " OK\ " name = \ " ok\ " />


</ DialogLayout

</ WindowCanvas

</ Dialog

八、绘图及事件处理


1 、绘图


STEP01. CWindowWnd::WndProc: 主窗口程序


STEP02. pThis -> HandleMessage: pThis是布局窗口对象指针,并与布局窗口绑定(SetWindowLongPtr)


STEP03. m_pm.MessageHandler: m_pm为CPaintManagerUI唯一实例对象


STEP04. CPaintManagerUI::MessageHandler: 处理WM_PAINT


STEP05. m_pRoot -> DoPaint: m_pRoot为最下层的控件对象,在本例中为CWindowCanvasUI控件(对应脚本中的WindowCanvas)


STEP06. CCanvasUI::DoPaint: 往画布上绘制背景色、边角弧形、水印等。


STEP07. CContainerUI::DoPaint: 在布局窗口(对应脚本中DialogLayout)画所有控件(控件实例对象保存在m_items中)


STEP08. pControl -> DoPaint: pControl为控件对象实例之一,利用多态性来调用不同控件的绘图方法


STEP09. CButtonUI::DoPaint: 按钮(对应脚本中Button)绘图方法,有下面两种方法


i)文字方法: CGUIRenderEngineUI::DPaintButton


ii)图片方法: CGUIRenderEngineUI::DoPaintBitmap


STEP10. 新一轮消息循环


2 、事件


STEP01. CWindowWnd::WndProc:


STEP02. pThis -> HandleMessage:


STEP03. m_pm.MessageHandler:


STEP04. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONDOWN


STEP05. CPaintManagerUI::FindControl: 根据鼠标坐标查找相应控件对象


STEP06. m_pRoot -> FindControl:


STEP07. CContainerUI::FindControl: 在布局窗口上查找相应控件对象


STEP08. CControlUI::FindControl: 在m_items中查找相对应的控件对象


STEP09. pControl -> Event: pControl为控件对象实例之一,利用多态性来调用不同控件的事件方法


STEP10. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONUP


STEP11. m_pEventClick -> Event: 利用多态性来调用不同控件的事件方法(m_pEventClick说明见 " 主要数据成员 " )


STEP12. CButtonUI::Event: 按钮(对应脚本中Button)事件方法


STEP13. CButtonUI::Activate:


STEP14. m_pManager -> SendNotify: 传递控件对象指针和触发事件(文本方式)


STEP15. CPaintManagerUI::SendNotify: 注意以下两点实现是完成控制和业务分离的关键


i)利用重载特性调用注册的监听对象(窗口)的消息处理函数Notify(监听对象保存在m_aNotifiers中)


for ( int i = 0 ; i [/span> m_aNotifiers.GetSize(); ++ i )


{


static_cast (m_aNotifiers【i】) -> Notify(Msg);


}


ii)布局窗口CStartPageWnd的消息处理,宏定义展开后实际就是重载的Notify函数


DIRECT_BEGIN_NOTIFYMAP(CStartPageWnd)


PROCESS_BUTTON_CLICK(_T( " ok " ),OnOk)


。。。


DIRECT_END_NOTIFYMAP(CStandardPageWnd)


STEP16. CStartPageWnd::OnOk: 控件消息处理函数,此处可以加入具体的事务逻辑处理


STEP17. 新一轮消息循环


3 、消息定义(文本)


" click " 、 " changed " 、 " link " 、 " browse " 、 " itemclick " 、 " itemselect " 、 " dropdown " 、 " itemactivate " 、 " headerdragging " 、 " headerclick " 、 " headerdragged " 、 " itemexpand " 、 " itemcollapse " 、 " windowinit " 、 " killfocus " 、 " setfocus " 、 " timer "


九、疑问


1 、Edit、Combox的下拉列表部分、ScrollBar、Tooltip控件是创建的实际窗口,这个与DirectUI思路还是有差别的


3 、控件是用文本形式来做标识的,消息类型是文本形式,是否改成数值型比较好

相关文章
|
存储 运维 IDE
|
数据安全/隐私保护 Windows
如何使用 SPICE client (virt-viewer) 来连接远程虚拟机桌面?
如何使用 SPICE client (virt-viewer) 来连接远程虚拟机桌面? 什么是SPICE? SPICE (Simple Protocol for Independent Computing Environments) 是一个用于虚拟化环境中的通讯协议。
5615 0
|
C++
HSmartWindowControl 之 显示图像
原文:HSmartWindowControl 之 显示图像 概述:使用Halcon在VS中的控件显示一张图片。 要点:使用了图像缩放和图像显示函数,以及鼠标滚轮响应函数。 1、创建WinForm项目 首先在VS中添加Halcon所需的控件HSmartWindowControl,参考上一篇:HSmar...
2764 0
|
4月前
|
人工智能 自然语言处理 JavaScript
17种RAG实现方法大揭秘
RAG(检索增强生成)通过结合外部知识库与LLM生成能力,有效解决大模型知识滞后与幻觉问题。本文详解三类策略、17种实现方案,涵盖文档分块、检索排序与反馈机制,并提供工程选型指南,助力构建高效智能系统。
1074 0
|
人工智能 前端开发 测试技术
探索软件测试中的自动化框架选择与优化策略####
本文深入剖析了当前主流的自动化测试框架,通过对比分析各自的优势、局限性及适用场景,为读者提供了一套系统性的选择与优化指南。文章首先概述了自动化测试的重要性及其在软件开发生命周期中的位置,接着逐一探讨了Selenium、Appium、Cypress等热门框架的特点,并通过实际案例展示了如何根据项目需求灵活选用与配置框架,以提升测试效率和质量。最后,文章还分享了若干最佳实践和未来趋势预测,旨在帮助测试工程师更好地应对复杂多变的测试环境。 ####
336 4
|
JSON API 数据处理
Winform管理系统新飞跃:无缝集成SqlSugar与Web API,实现数据云端同步的革新之路!
【8月更文挑战第3天】在企业应用开发中,常需将Winform桌面应用扩展至支持Web API调用,实现数据云端同步。本文通过实例展示如何在已有SqlSugar为基础的Winform系统中集成HTTP客户端调用Web API。采用.NET的`HttpClient`处理请求,支持异步操作。示例包括创建HTTP辅助类封装请求逻辑及在Winform界面调用API更新UI。此外,还讨论了跨域与安全性的处理策略。这种方法提高了系统的灵活性与扩展性,便于未来的技术演进。
617 2
【51单片机】静态数码管显示(设计思路&原理&代码演示)
【51单片机】静态数码管显示(设计思路&原理&代码演示)
|
SQL 存储 小程序
【教程】navicat配合HTTP通道远程连接SQLite数据库
本文介绍了如何通过 Navicat Premium 工具配合 n_tunnel_sqlite.php 和 HTTP 通道远程连接服务器上的 SQLite 数据库。SQLite 是一种自给自足的、无服务器的 SQL 数据库引擎,由于其端口未对外开放,直接使用 Navicat 进行远程连接不可行。文章详细记录了使用 HTTP 通道实现远程连接的过程,包括定位本地 `ntunnel_sqlite.php` 文件,将其上传至服务器,并通过 Navicat 配置 HTTP 通道连接 SQLite 数据库的具体步骤。
1053 0
【教程】navicat配合HTTP通道远程连接SQLite数据库
|
设计模式 Java 开发者
Head First设计模式详解与应用场景分析
Head First设计模式详解与应用场景分析
|
消息中间件 NoSQL 调度
Django后端架构开发:Django 与 Celery 的深度集成
Django后端架构开发:Django 与 Celery 的深度集成
822 0