采用此GUI实现的WNIDWS的界面与传统的window界面不同,传统的WINDOWS界面是用户窗口的层次排列,这种方式有很多局限性。目前的开发环境我们可以很快的使用win32控件构造出标准的干净的界面,但是我们同时也会立刻意识到如果我想要界面更加漂亮,更加炫一点就比较麻烦了。Windows控件提供的Custom-Draw/Ower-Draw技术局限太多,基本上没有透明等效果支持,同时控件布局方面也比较古板。此GUI是基于绘制出更加美观的界面效果以及更加灵活的使用控件的目的而编写的,眼下流行的叫法为DirectUI技术。
DirectUI的设计初衷是去除窗口的概念,所有的元素都是逻辑上的窗口,而不是真正意义上有句柄的窗口。即这些元素都是直接在"父窗口"中绘制并响应事件。这个也不是什么新的思路,VCL(Borland C++ Builder中的可视化组件)中早就有这种实现,VCL的TControl和从TControl继承的类都可以响应事件,而从TControl继承的可以是无句柄的组件。所以看看VCL的设计,就大概知道一个无句柄的DirectUI应该如何设计了。
DirectUI 最早的应用是在拿spy++捕获microsoft的NSN窗口时发现的。国外如微软,国内如腾讯,百度等公司的客户端产品多采用DirectUI来组织界面。所有的大型网游客户端基本上都是使用DirectUI的方式来创建的,所不同的是,普通的应用程序的DirectUI方式界面库中如Edit,ComboBox,ListCtrl等复杂控件还是使用win32控件来创建的,其虚拟的只是Static,Button,progressBar等控件。而一些大型的游戏客户端可能这些元素可能也是自己处理。
在DirectUI中没有了句柄和窗口的概念,首先得一个好处是要做一些好的界面效果变得更加容易。举例来说在有窗口句柄时要实现Static,Button等控件是见麻烦的事,Static还好说,win32有WM_CTRLCOLOR消息支持,可以做透明,Button或者别的控件就麻烦了,需要采用发消息给父窗口,让父窗口在子窗口的DC上先绘制,然后子窗口再绘制自己的TEXT。而在DirectUI下,这种效果简直太简单了,子元素只绘制自己的Text,那就是透明效果。这中情况下,很容易做出带底纹的,比较炫一些的界面。另一个好处就是一些效率问题,现在我们实际上处理的界面只有父窗口,如果我们实现皮肤换色,换肤等效果,效率要提高许多。实际上我们处理的界面或者说DC要少了很多,这样效率或者逻辑应该就相对简单了,同时对系统资源的占用也少了很多。
这种界面设计方式的最大的好处在于可以很方便的构建高效,绚丽的,非常易于扩展的界面。从而很好的将界面和逻辑分离,同时易于实现各种超炫的界面效果如换色,换肤,透明等。DirectUI技术旨在满足客户端界面快速开发的需要,同时融入业界前沿的皮肤技术,为用户创建更加高效,专业的界面。
对于使用DirectUI的窗口,如何解决找到他的“子窗口”的位置和其他“属性”这一问题,位置是一个区分消息分配的重要条件,但不是唯一条件。一般实现DirectUI的库里面都会采用配置文件或者XML来描述界面,这样程序在加载的时候实际上就已经得到了一个所有控件位置的表,而DirectUI中控件的属性肯定是自己根据需要来定义的,比如left,top,width,height,是否透明等。还是需要有个对象如DirectUIButton来和这个虚拟的对象绑定的。
主要就是分割区域然后画了,至于他们怎么知道位置,很简单,里面有对象来处理这些,比如你的鼠标在(x,y)单击了一下,父窗口就会向所有的子对象(内部对象,没有Handle属性)转发这个消息,或者查找位于这个位置的最上层对象,然后转发消息给他,这样就可以做到那个对象响应这个消息了(和Button处理方式一样,只是没有句柄了,也不依赖于Windows来分发消息)。至于WM_Paint消息比较好处理,父窗口先将底色画好,然后就分发这个消息给所有子对象,子对象根据自己记录的位置和范围,在指定的Rect中画好自己的东西就可以了。
总之要注意一点,采用此GUI类库实现的WINDOWS应用只有一个主窗口,其它的窗口部件都是在其父窗口中画出来的虚拟窗口。
在此GUI库中的窗口部件基类csp_widget中的WidgetList类型成员 mlst_its_children和add_children方法用来向“父窗口”中添加子窗口部件,在应用程序退出时,csp_widget的析构函数调用clear_children方法来释放子窗口部件。下载本文