原文见:https://www.jianshu.com/p/ebdacd2343e3 关于DirectUI的一些思考
目录
对于传统Win32界面编程来讲,微软提供一整套界面标准,比如窗口、按钮、滚动条、列表等。对于每一个窗口(控件也是一个窗口),其能响应的消息和行为都有规范(通过API提供给开发者)。微软这套界面标准是为通用场景下提出的解决方案,能够满足绝大部分需求,但业务场景的多样性,使得开发者们并不满足于这套界面标准。
● 2005年6月,Bjarke Viksoe发布了一篇文章UI: Become windowless, 阐述了无窗口句柄(windowless)思想。
● 2010年12月,金山网络宣布启动金山卫士开源计划,该开源项目以失败告终,但有热心的网友从该项目中分离了金山卫士的界面部分成为一个独立的项目bkwin。
● 2012年之后,由bkwin项目衍生出各种基于DirectUI思想的开源框架,如Duilib、DuiEngine、DuiVision、SOUI等。
DirectUI是一种界面开发思想。其核心思想是指将所有的界面控件都绘制在一个窗口上,这些控件的逻辑和绘制方式都必须自己进行编写和封装,而不是使用Windows的原生控件,所以这些控件都是无句柄的(Windowsless)。也就是说主窗口是有句柄HWND的,但是子控件Button List等等都是无窗口句柄的,使用spy++无法抓取控件的HWND。
那这个名称是怎么来的呢?由于Windows有句柄窗口是一套工业标准,窗口消息和API都是公开的,所有人都知道怎么操作窗口。微软在做MSN的时候为了保护用户隐私,搞了一个DirectUIHWND窗口类,意为Paint on parent dc directley(直接在父窗口上绘图),即子窗口不以窗口句柄的形式创建,只是逻辑上的窗口,绘制在窗口之上。通俗来说就是在窗口上指定一块区域(仅仅是一个区域,不是一个实体控件)通过各种消息模拟一个控件的功能。完全可以在一个对话框类的OnMouseMove、OnLButton等函数中模拟一个区域(仅仅是一个区域,不是一个实体控件)通过各种消息模拟一个按钮出来。但是模拟的控件一多就混乱了,为了统一管理,逻辑更清晰,类似于实体控件,把每种控件封装成类处理各种消息,并通过自定义的消息分发机制把消息分发到各个模拟控件里。
后边DirectUI这个名字就被沿用下来,后边说的DirectUI一般都是指无句柄窗口。
DirectUI实际是在Windows的原生窗口基础上,更细粒度地进行窗口控制,它需要建立一套自己DirectUI标准,主要需要解决以下问题:
● 窗口子类化,截获窗口消息;
● 封装自己的控件,并将控件绘制到窗口上;
● 封装窗口消息,并分发到自己的控件上,让自己的控件根据消息进行相应绘制;
● 根据不同行为发送自己定义消息给窗口,以便客户程序处理;
● 界面与逻辑分离,一般使用XML来描述窗口上控件布局;
窗口子类化:
https://blog.csdn.net/lwbeyond/article/details/5393495 窗口子类化
https://blog.csdn.net/bjbz_cxy/article/details/80762692 Windows核心编程_窗口子类化
https://www.cnblogs.com/wjl4934/archive/2012/07/16/2593173.html 窗口子类化
相较于传统Win32界面,DirectUI技术有以下优势:
● 界面逻辑完全分离:DirectUI将界面布局完全分离出来(通常采用XML进行描述),将逻辑与界面解耦,符合界面设计原则。
● 防止软件被破解:由于DirectUI是建立在Win32界面标准之上,其DUI窗口(子控件也是一个DUI窗口)的消息转发和消息处理因框架设计的不同而异,这些内部逻辑对外不透明,很难破解。我想这也是很多大厂不想开源其界面框架的原因之一吧。
● 运行效率更高:这个取决于DirectUI框架的实现。由于是在框架内部进行消息转发和处理,并不需要经过系统,理论上效率会更高。
● 更容易实现绚丽效果和换肤功能:DirectUI框架提供标准控件的同时也提供良好的扩展性。业务层在框架基本上可以很容易定制自己的控件