如何給開源的DUILib支持Accessibility

最近的工做是給開源的DUILib支持Accessibility, 一些經驗記錄並分享下。html

 

微軟的Accessibility其實Windows平臺上一個挺重要的東西, 儘管在國內不受重視,可是若是你的軟件要出口歐美,Accessibility是必須的, 否則國外正規單位(政府,學校,大公司等)是禁止採購的。

 

若是咱們的軟件用的是Winodws標準控件,通常Accessibility是系統默認內置支持的 (固然這也不是必定的,據我測試系統的Date Time Picker控件是不支持MSAA的)。由於系統標準控件在展示和行爲上的一些限制以及自繪的複雜性,愈來愈多的軟件使用DirectUI技術,關於使用DirectUI的理由,更多參見<< 如何讓窗口控件半透明 >>和<< 軟件換膚的原理 >>.

國內最有名的的DirectUI界面庫固然是 開源的 DUILib (儘管這套庫已中止更新), 實際上我之前在本身業餘寫點東西時, 也參考過它, 具體參見<< 開源一套DirectUI界面庫 >>。對於開源的DUILib, 我的以爲它有挺多優勢, 也有挺多缺點, 咱們重點說缺點, 由於這是咱們改進的方向。

1。擴展性差
    DUILib只實現了一些基本的控件,好的DirectUI庫能夠經過基本控件組合來輕鬆實現複雜控件,而要達到這個效果, 不少時候咱們須要攔截子控件的消息, 儘管DUILib提供了delegate機制來子類化子控件, 可是這樣消息攔來攔去實在太不方便了,不少時候本身都轉暈了。我的覺的這裏咱們能夠引入WPF的隧道和冒泡機制, 這個東西對DirectUI界面庫實在過重要了。

 

2。不支持Layered窗口
要完美支持Layered窗口,意味着全部的Render全都要支持Alpha通道, DUILib使用GDI, 若是沒有特殊處理,意味着無法完美支持Layered窗口, 我這篇也談到過這個問題<< 如何基於純GDI實現alpha通道的矢量和文字繪製 >>。

 

3。大數據時性能不行
DUILib不少時候只適合作些簡單的界面,自己控件基類很龐大,數據量方面對於幾百條數據還行,可是對於成千上萬條數據就吃不消了,這時咱們須要引入WPF的虛表機制。
 

4。不支持圖文排版前端

儘管DUILib支持簡單的HTML排版, 可是畢竟太簡單,若是咱們要在QQ那樣的聊天窗口裏引入就吃不消了, 另外它渲染HTML那個代碼我是吃不消看的。

 

5. 基本不支持Accessibility

 

6。其餘
接口和屬性定義太隨意, 採用導出類的方式也很差擴充, 渲染方面最好能在GDI/GDI+/Direct2D方面進行切換,最好將核心控件和擴展控件分離開, 編輯器也太簡陋。

 

今天咱們重點說Accessibility,一個界面庫要完整支持Accessibility, 要包括太多東西 (具體能夠參見控制面板裏的"輕鬆訪問中心"),我估計只有微軟本身作的到(好比WPF), 這也是 不少人推薦系統標準控件而排斥DirectUI的理由。 咱們說的Accessibility不少時候只是簡化版, 下面咱們說重點的幾條。

 

1。鍵盤支持
鍵盤支持簡單來講就是即便我沒有鼠標, 我也能經過經過鍵盤完成全部操做。它主要包括鍵盤導航和控件的鍵盤支持。鍵盤導航主要是指我能夠經過一些熱鍵(如F6)能夠在不一樣窗口(Panel)之間進行焦點切換, 我能夠經過Tab/Shift+Tab在窗口內不一樣控件之間進行焦點導航。控件的鍵盤支持也是不少國內DirectUI庫所缺失的,好比:
Dialog: Enter執行默認, ESC退出並關閉
Button:空格執行
CheckBox:空格取反
Radio:空格取反,上下左右鍵切換選中項
TabCtrl:焦點選中時上下左右切換, 焦點沒選中時Ctrl+Tab/ Ctrl+Tab+Shift切換Tab頁
Menu:上下左右導航,Enter執行, ESC取消關閉, 具體參見<< DirectUI中模態對話框和菜單的原理 >>
....
總之,DUILib在鍵盤支持這塊已經作了很多工做,可是還有挺多事要作,每一個控件都要完整支持鍵盤是個很精細的活。

 

2。讀屏軟件和自動化測試的支持。 
ScreenReader(讀屏器)主要是給盲人用的, 程序能夠實時的把得到焦點的控件和系統發生的事件播報出來, 不少讀屏軟件都須要收費,還好Win7以後系統已自帶讀屏軟件(控制面板\輕鬆訪問\輕鬆訪問中心\啓動講述人)。自動化測試時也須要工具可以理解咱們界面中包含的元素類型和位置, 以及模擬操做事件等。

 

DirectUI要支持讀屏和自動化測試通常有2種方式, MSAA和UI Automation。 MSAA是比較古老的方式,主要就是實現IAccessible接口;UI Automation是微軟特地給WPF新增長的。MSAA出來的時候仍是Win95, 由於歷史緣由有一些限制, 好比不支持Text控件,無法描述複雜控件等, 因此微軟後來引入了UI Automation, 具體參見<< Windows GUI自動化測試技術的比較和展望 >>。 

 

MSAA最大的優勢是穩定, 因此我在DUILib裏採用MSAA來實現ScreenReader的支持。簡單說下幾個關鍵點:
(a) 每一個控件啊實現IAccessible接口的Proxy對象儘可能獨立,裏面保存一個控件指針的引用,這樣即便控件銷燬了,Proxy對象能夠依舊存在(系統仍可能會訪問這個對象)。
(b) 按照控件的層次體系,實現每種控件的Proxy類(實現IAccessible接口)。
(c) WM_GETOBJECT請求OBJID_CLIENT時返回根節點的Proxy對象, 焦點變化時通知觸發事件NotifyWinEvent(EVENT_OBJECT_FOCUS, m_hWndPaint,  (LPARAM)m_pFocus, CHILDID_SELF), 窗口收到 WM_GETOBJECT消息時根據ObjectID(這裏是控件指針)找到該控件, 而後返回該控件的Proxy。 (這是關鍵,這個問題鬱悶了我很久的...) 

 

3。高對比(high contrast)的支持
高對比,主要是給色盲用,這個東西通常自繪程序都不會支持, 即便你是用標準控件,由於 通常會用本身漂亮的圖片和色彩來表現界面, 高對比實現 的關鍵點是你在畫每一個元素時要經過GetSystemColor來獲取顏色。據我測繪除了微軟本身的程序, 其餘越是漂亮的軟件越是不支持高對比(即便如QQ和Chrome)。

 

4。高DPI的支持
隨着Surface Pro和高分辨率設備的流行,程序對高DPI的支持正變得愈來愈重要, 具體參見<< 關於Windows高DPI的一些簡單總結 >>。傳統的基於標準控件的程序要支持高DPI是在太難了,因此微軟纔有了DWM虛擬化。可是DirectUI對高DPI的支持有着自然的優點, 咱們徹底能夠在界面庫這層讓程序完美支持高DPI, 界面的渲染主要是文字, 矢量 和圖片, 文字和矢量徹底能夠經過無損縮放繪畫實現,圖像能夠經過適當縮放和換圖來實現。

總結下,儘管我N次吐槽基於GDI的DirectUI界面庫會隨着XP的淡出而逐漸失去市場, 可是實際工做中仍是要常常和GDI打交道,外面招聘單位仍是有很多Windows客戶端的開發崗位。 在這"移動互聯和"Web前端"橫行的"大數據"時代,不少同事開始向移動App和大數據轉型, 儘管這幾年PC客戶端的開發人員是隻出不進, 可是隻要Windows存在一天,咱們的工做就仍是有價值的..
相關文章
相關標籤/搜索