标签:des class blog code http tar
DirectUI的初步分析(一)
最近由于项目的需要学习了一下DirectUI方面的东西,主要借鉴的是一个国外程序员写的代码(见引用一),看了后发现它更多的是探讨一种实现的可能性和思路,和实际应用还是有距离的,不过其实现还是很有意思的。在写此小结的时候又发现国内一个程序员将这个代码部分移植到WINCE下的代码(见引用二),因为平台的差异性要完全开发一个WINCE下的实际代码还是需要时间的。由于本人GUI开发做得少,工作中有关这方面的东西主要是提供思路和方法,学习DirectUI的主要目的是为了更新知识学习思路,文章中难免出现错误。 一、核心1、CWindowWnd: 窗口对象类(窗口实例对象父类)2、CDialogBuilder: 创建控件类,分析脚本并用递归方式(_Parse函数)创建所有控件实例3、CPaintManagerUI: 窗口消息及图形绘制管理器类4、CGUIRenderEngineUI: 图形渲染引擎类,在离屏DC中生成最终显示的图形,可根据需要扩展多种图形效果显示。5、INotifyUI: 事件通知抽象类6、IMessageFilterUI: 消息过滤抽象类 二、控件CControlUI: 控件管理抽象父类,父类INotifyUI1、buttonCButtonUI: 按钮控件COptionUI: 选择按钮控件 2、comboxCSingleLinePickUI: CDropDownUI: 下拉控件,父类另有CContainerUI和IListOwnerUI 3、decorationCTitleShadowUI: 阴影效果CListHeaderShadowUICSeparatorLineUICFadedLineUI 4、editCSingleLineEditUI: 单行编辑框控件CMultiLineEditUI: 多行编辑框控件 5、labelCLabelPanelUI: 可设置背景色和文字色的静态标签控件CGreyTextHeaderUI 6、list第一种:CListUI: 列表控件,包含以下几个子控件(1)CListHeaderItemUI: 列表头(2)CListExpandElementUI: 列表项第二种:用法不明CListHeaderUI: 列表头CListElementUI: 列表项,父类另有IListItemUICListLabelElementUI: 列表项,父类CListElementUICListTextElementUI: 列表项CListFooterUI: 列表尾 7、panelCTextPanelUI: 父类CLabelPanelUICTaskPanelUI: CNavigatorPanelUI: 导航面板,父类另有IListOwnerUI,包含CNavigatorButtonUI子控件CSearchTitlePanelUI: CImagePanelUI: 图片显示CWarningPanelUI: 警告提示,父类CTextPanelUICPaddingPanelUI: 填充栏 8、tabCTabFolderUI: 父类另有CContainerUI和IListOwnerUICTabPageUI: 父类另有CContainerUI 9、toolbarCToolbarUI: 工具栏,包含以下几个子控件(1)CToolButtonUI: 图形按钮(2)CToolSeparatorUI: 分隔符(3)CToolGripperUI: gripper 10、titleCToolbarTitlePanelUI: 11、statusbarCStatusbarUI: 状态栏,父类另有CContainerUI 12、animCAnimJobUI: 动画显示类 13、ActiveXCActiveXUI: 三、容器:CContainerUI: 容器类,父类CControlUI和IContainerUI。可以认为容器是特殊的控件(见上面控件类关于父类的说明),其目的之一是具有容器特性的控件可以容纳其它控件,这样可以方便的实现控件的叠加;目的之二实际的窗口只有一个,对于叠加的控件必须要进行层次管理才能正确绘图和事件分发。另外可参见引用三1、画布: CCanvasUI(父类CContainerUI),可绘制背景色、画线、贴图CWindowCanvasUI: 父类CCanvasUICControlCanvasUI: 父类CCanvasUICWhiteCanvasUI: 父类CCanvasUICDialogCanvasUI: 父类CCanvasUICTabFolderCanvasUI: 父类CCanvasUI 2、布局: 管理不同层次的控件CDialogLayoutUI: 父类CContainerUICVerticalLayoutUI: 父类CContainerUICHorizontalLayoutUI: 父类CContainerUICTileLayoutUI: 父类CContainerUI 四、通用1、scriptCMarkupCMarkupNode 2、languageCUIUtility 3、multi-threadCriticalSectionAutoCriticalSectionCMutexCAutoMutexCEventCAutoEventCManualEvent 五、主要数据成员1、CPaintManagerUICControlUI* 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: 控件布局窗口设备DCHDC m_hDcOffscreen: 离屏内存DCHBITMAP m_hbmpOffscreen: 离屏内存DC相关联HBITMAP 2、CControlUICPaintManagerUI* m_pManager: 窗口消息或绘图管理器CControlUI* m_pParent: 逻辑上的父窗口(控件)对象指针CStdString m_sName: 控件标识CStdString m_sText: 控件显示标题或显示脚本字符串CStdString m_sToolTip: 控件的Tip信息 3、CContainerUICStdPtrArray m_items: 同一层的控件对象或控件对象的子对象,例如canvas上放置的按钮、combox由edit和list两个子对象组成,其它还有tab等。具体见CDropDownUI、CTabFolderUI、CNavigatorPanelUI三个类定义 4、CDialogLayoutUICStdValArray m_aModes: 用于存放在Layout上绝对坐标转成相对坐标(CDialogLayoutUI::RecalcArea)的控件对象(指针、大小、模式),目的是否为了让布局上的控件随布局变化而变化,能够正确绘图??? 六、控件属性待完成 七、脚本例子<Dialog> <WindowCanvas pos=/"0,0,600,800/"> <DialogLayout pos=/"0,0,600,800/"> <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_PAINTSTEP05. m_pRoot->DoPaint: m_pRoot为最下层的控件对象(在本例中为CWindowCanvasUI控件,对应脚本中的WindowCanvas)STEP06. CCanvasUI::DoPaint: 往画布上绘制背景色、边角弧形、水印等。STEP07. CContainerUI::DoPaint: 在最下层具有容器特性的控件(CWindowCanvasUI控件)上画容器内所有控件(控件实例对象保存在m_items中)STEP08. pControl->DoPaint: pControl为控件对象实例之一,利用多态性来调用不同控件的绘图方法STEP09. CButtonUI::DoPaint: 按钮(对应脚本中Button)绘图方法,有下面两种方法i)文字方法: CGUIRenderEngineUI::DPaintButtonii)图片方法: CGUIRenderEngineUI::DoPaintBitmapSTEP10. 新一轮消息循环 2、事件STEP01. CWindowWnd::__WndProc: STEP02. pThis->HandleMessage: STEP03. m_pm.MessageHandler: STEP04. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONDOWNSTEP05. CPaintManagerUI::FindControl: 根据鼠标坐标查找相应控件对象STEP06. m_pRoot->FindControl: STEP07. CContainerUI::FindControl: 在最下层具有容器特性的控件(CWindowCanvasUI控件)容器内查找相应控件对象STEP08. CControlUI::FindControl: 在m_items中查找相对应的控件对象STEP09. pControl->Event: pControl为控件对象实例之一,利用多态性来调用不同控件的事件方法STEP10. CPaintManagerUI::MessageHandler: 处理WM_LBUTTONUPSTEP11. 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 < m_aNotifiers.GetSize(); ++i ){ static_cast<INotifyUI*>(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思路还是有差别的2、实例中有创建一个不进行消息处理的窗口(CFrameWindowWnd),然后又创建了一个窗口(CStandardPageWnd)用于具体的控件布局。但是我用一个窗口也能实现,原作者为什么这样还不清楚3、控件是用文本形式来做标识的,消息类型是文本形式,是否改成数值型比较好 十、引用引用一: http://www.viksoe.dk/code/windowless1.htm引用二: http://directui.googlecode.com/引用三: http://www.cnblogs.com/cutepig/archive/2010/06/14/1758204.html |
DirectUI的初步分析(二)
这篇文章是<DirectUI的初步分析>后的延续,在本文中主要是针对整体的框架结合MVC模式来进行分析,不会涉及具体的代码。 (1)Subject(目标)I)目标知道它的观察者。可以有任意多个观察者观察同一个目标。II)提供注册和删除观察者对象的接口。目标应该就是CControlUI类,关于第一点观察者观察的是CControlUI,当多个观察者观察的同一个目标状态发生改变时也就是多视图更新;关于第二点CControlUI中并没有定义这样的接口,这个工作是由CPaintManagerUI来完成的,不过没有再另行定义虚接口类。CPaintManagerUI的功能不仅限于此,还完成了更多的工作,会在下面做详细描述。(2)Observer(观察者)为那些在目标发生改变时需获得通知的(观察者)对象定义一个更新接口。INotifyUI虚接口类的Notify函数。关于这一点单纯的观察者模式是有缺点的,如果存在多个观察者对象那就要为每一个观察者对象定义一个同名方法(即虚函数Notify)这加大了开销。如果用委托那观察者对象的方法就可以不同名(将观察者对象的方法委托给目标)(3)ConcreteSubject(具体目标)I)将有关状态存入各ConcreteObserver对象。II)当它的状态发生改变时,向它的各个观察者发出通知。应该就是继承自CControlUI或CContainUI等的各种控件类,当有事件触发时会通知观察者对象。关于第一点如进度条拖动时通知观察者对象获取值;关于第二点如按钮按下通知观察者(4)ConcreteObserver(具体观察者)I)维护一个指向ConcreteSubject对象的引用II)存储有关状态,这些状态应与目标的状态保持一致III)实现Observer的更新接口以使自身状态与目标的状态保持一致派生自INotifyUI的类如CStandardPageWnd,它实现了Notify虚函数、根据名称或ID获得控件实例对象指针、根据控件通知保存值或控件状态等等。(5)众所周知MVC方式是从观察者模式演变而来。从第(4)描述来看CStandardPageWnd做为观察者并没有更新视图,原因何在?视图更新的工作实际上由CPaintManagerUI来承担了,这样做的好处就是当目标状态或数据发生改变时视图能立即更新反映变化,观察者收到通知后只需关注状态存储或数据处理,这也是文档视图的分离。(6)我们知道WINDOW操作系统是基于窗口和消息的系统,所以目标状态的改变也是基于窗口消息触发而改变。CStandardPageWnd的父类CWindowWnd完成了这一部分同平台紧密相关的工作,而CPaintManagerUI完成了消息处理及改变目标状态的工作,理论上来说如果把这两部分加上相对独立的渲染部分替换就可以实现跨平台了。是否可以认为这些是控制器完成的工作? |
DirectUI的初步分析(三)
基于(http://directui.googlecode.com/)最新版r62进行分析,对于未使用的控件属性未做分析 属性一、主窗口属性(XML中标签‘Window‘)size 窗口的大小sizebox caption 标题栏的宽度高度roundcorner 窗口的圆角矩形的半径mininfoshowdirty 是否用矩形框标示需要重画的区域 二、公共属性(‘Window‘标签和第一个容器标签间的内容)Image 图片的来源以及图片文件的名称,一般是用于html方式文字的标签{i}Font 字体配置方案,对应CLabelUI的font属性Default 指定Button、VScrollBar、HScrollBar的几种状态图片属性 三、控件(容器)属性CControlUI 1 float 和pos组合使用,根据所处容器窗口坐标计算其窗口坐标。如果不指定此属性则背景图片会拉伸到整个容器,文字会水平居左垂直居中显示2 pos 同上3 padding 控件文字显示位置缩进距离4 bkcolor 第一种背景颜色,如果指定第二种背景颜色则背景为垂直方向的渐变色5 bkcolor2 第二种背景颜色6 bordercolor 边框线颜色7 bordersize 边框线尺寸8 bkimage 背景图片9 width 10 height11 minwidth12 minheight13 maxwidth14 maxheight15 name 控件标识,在同一窗口内具有唯一性16 text 显示文字17 tooltip tip信息18 userdata 扩展用户数据19 enabled 是否激活20 mouse 是否响应鼠标消息,如果为false则由其最近的左兄弟或父亲结点处理21 visible 是否可见22 shortcut23 relativepos 子控件(容器)相对于父控件(容器)的客户区坐标 CContainerUI -> CControlUI1 inset 容器内的控件的可显示区域要上下左右各缩进多少;如果容器嵌套容器则用于指定子容器相对父容器的偏移2 mousechild 3 vscrollbar 垂直滚动条的几种状态图片属性4 hscrollbar 水平滚动条的几种状态图片属性5 childpadding CHorizontalLayoutUI -> CContainerUI1 sepwidth2 sepimm CTileLayoutUI -> CContainerUI1 columns 容器内控件按几列显示,会自动根据列数计算行数 CLabelUI -> CControlUI1 align 文字对齐方式2 font 文字字体属性3 textcolor 文字颜色4 disabledtextcolor 非激活状态下文字颜色5 textpadding 6 showhtml html方式显示文字,可参考DrawHtmlText函数说明7 fitallArea 状态图片是否需要填充整个区域,false可以用来画checkbox & radio box8 tipimage tip的背景图片 CButtonUI -> CLabelUI -> CControlUI1 normalimage 正常状态图片2 hotimage 高亮状态图片3 pushedimage 按下状态图片4 focusedimage 获得焦点状态图片5 disabledimage 非激活状态图片6 disabled COptionUI -> CButtonUI -> CLabelUI -> CControlUI1 group 为true则表示是多个option组合使用,且所有option必须包含在容器内。2 selected 初始状态为选中,如果指定了group属性则当前选中项只有一个,而且属性字符中group要位于selected前面。3 selectedimage 选中状态图片4 foreimage checkbox或radio box选中时前景小图片5 selectedtextcolor 文字颜色 CTextUI -> CLabelUI -> CControlUI CProgressUI -> CLabelUI -> CControlUI1 fgimage 前景进度条图片,一般是根据百分比做拉伸处理2 hor 为true则水平显示3 min 最小值4 max 最大值5 value 当前值 CSliderUI -> CProgressUI -> CLabelUI -> CControlUI1 thumbimage 滑标正常状态图片2 thumbhotimage 滑标高亮状态图片3 thumbpushedimage 滑标按下状态图片4 thumbsize 滑标大小注:如果需要实现带轨道的滑动条控制,则需要指定父类CControlUI的bkimage属性;如果要实现计数,则需要指定父类CProgressUI的min/max/value属性 CEditUI -> CLabelUI1 readonly 只读属性2 password 密文"*"显示方式3 normalimage 正常状态图片4 hotimage 高亮状态图片5 focusedimage 获得焦点状态图片6 disabledimage 非激活状态图片7 multiline 多行属性8 maxchar 是大可输入字符数 CComboUI -> CContainerUI -> CControlUI1 textpadding2 normalimage3 hotimage4 pushedimage5 focusedimage6 disabledimage7 itemfont8 itemalign9 itemtextpadding10 itemtextcolor11 itembkcolor12 itemimage13 itemselectedtextcolor14 itemselectedbkcolor15 itemselectedimage16 itemhottextcolor17 itemhotbkcolor18 itemhotimage19 itemdisabledtextcolor20 itemdisabledbkcolor21 itemdisabledimage22 itemlinecolor23 itemshowhtml CScrollbarUI -> CControlUI1 button1normalimage2 button1hotimage3 button1pushedimage4 button1disabledimage5 button2normalimage6 button2hotimage7 button2pushedimage8 button2disabledimage9 thumbnormalimage10 thumbhotimage11 thumbpushedimage12 thumbdisabledimage13 railnormalimage14 railhotimage15 railpushedimage16 raildisabledimage17 bknormalimage18 bkhotimage19 bkpushedimage20 bkdisabledimage21 hor22 linesize23 range24 value CListUI -> CVerticalLayoutUI -> CContainerUI1 header2 headerbkimage3 expanding4 multiexpanding5 itemfont6 itemalign7 itemtextpadding8 itemtextcolor9 itembkcolor10 itemimage11 itemselectedtextcolor12 itemselectedbkcolor13 itemselectedimage14 itemhottextcolor15 itemhotbkcolor16 itemhotimage17 itemdisabledtextcolor18 itemdisabledbkcolor19 itemdisabledimage20 itemlinecolor21 itemshowhtml CListHeaderItemUI -> CControlUI1 dragable2 sepwidth3 align4 font5 textcolor6 showhtml7 normalimage8 hotimage9 pushedimage10 focusedimage11 sepimage CListElementUI -> CControlUI1 selected CListExpandElementUI -> CListTextElementUI -> CListLabelElementUI -> CListElementUI -> CControlUI1 expander2 hideself CListContainerElementUI -> CContainerUI1 selected |
DirectUI的初步分析-转,布布扣,bubuko.com
标签:des class blog code http tar
原文地址:http://www.cnblogs.com/Bonker/p/3773002.html