原文見:https://www.jianshu.com/p/ebdacd2343e3 關於DirectUI的一些思考
目錄
1. DirectUI的發展歷史
對於傳統Win32界面編程來講,微軟提供一整套界面標準,比如窗口、按鈕、滾動條、列表等。對於每一個窗口(控件也是一個窗口),其能響應的消息和行爲都有規範(通過API提供給開發者)。微軟這套界面標準是爲通用場景下提出的解決方案,能夠滿足絕大部分需求,但業務場景的多樣性,使得開發者們並不滿足於這套界面標準。
● 2005年6月,Bjarke Viksoe發佈了一篇文章UI: Become windowless, 闡述了無窗口句柄(windowless)思想。
● 2010年12月,金山網絡宣佈啓動金山衛士開源計劃,該開源項目以失敗告終,但有熱心的網友從該項目中分離了金山衛士的界面部分成爲一個獨立的項目bkwin。
● 2012年之後,由bkwin項目衍生出各種基於DirectUI思想的開源框架,如Duilib、DuiEngine、DuiVision、SOUI等。
2. 什麼是DirectUI
DirectUI是一種界面開發思想。其核心思想是指將所有的界面控件都繪製在一個窗口上,這些控件的邏輯和繪製方式都必須自己進行編寫和封裝,而不是使用Windows的原生控件,所以這些控件都是無句柄的(Windowsless)。也就是說主窗口是有句柄HWND的,但是子控件Button List等等都是無窗口句柄的,使用spy++無法抓取控件的HWND。
那這個名稱是怎麼來的呢?由於Windows有句柄窗口是一套工業標準,窗口消息和API都是公開的,所有人都知道怎麼操作窗口。微軟在做MSN的時候爲了保護用戶隱私,搞了一個DirectUIHWND窗口類,意爲Paint on parent dc directley(直接在父窗口上繪圖),即子窗口不以窗口句柄的形式創建,只是邏輯上的窗口,繪製在窗口之上。通俗來說就是在窗口上指定一塊區域(僅僅是一個區域,不是一個實體控件)通過各種消息模擬一個控件的功能。完全可以在一個對話框類的OnMouseMove、OnLButton等函數中模擬一個區域(僅僅是一個區域,不是一個實體控件)通過各種消息模擬一個按鈕出來。但是模擬的控件一多就混亂了,爲了統一管理,邏輯更清晰,類似於實體控件,把每種控件封裝成類處理各種消息,並通過自定義的消息分發機制把消息分發到各個模擬控件裏。
後邊DirectUI這個名字就被沿用下來,後邊說的DirectUI一般都是指無句柄窗口。
3. 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 窗口子類化
4. DirectUI的優勢
相較於傳統Win32界面,DirectUI技術有以下優勢:
● 界面邏輯完全分離:DirectUI將界面佈局完全分離出來(通常採用XML進行描述),將邏輯與界面解耦,符合界面設計原則。
● 防止軟件被破解:由於DirectUI是建立在Win32界面標準之上,其DUI窗口(子控件也是一個DUI窗口)的消息轉發和消息處理因框架設計的不同而異,這些內部邏輯對外不透明,很難破解。我想這也是很多大廠不想開源其界面框架的原因之一吧。
● 運行效率更高:這個取決於DirectUI框架的實現。由於是在框架內部進行消息轉發和處理,並不需要經過系統,理論上效率會更高。
● 更容易實現絢麗效果和換膚功能:DirectUI框架提供標準控件的同時也提供良好的擴展性。業務層在框架基本上可以很容易定製自己的控件