最近的工作是给开源的DUILib支持Accessibility, 一些经验记录并分享下。

微软的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存在一天,我们的工作就还是有价值的..

如何给开源的DUILib支持Accessibility的更多相关文章

  1. 如何给开源的DUILib支持Accessibility(论述了DUILib的六个缺点,很精彩)

    最近的工作是给开源的DUILib支持Accessibility, 一些经验记录并分享下.   微软的Accessibility其实Windows平台上一个挺重要的东西, 尽管在国内不受重视,但是如果你 ...

  2. 利用cocoapods管理开源项目,支持 pod install安装整个流程记录(github公有库)

    利用cocoapods管理开源项目,支持 pod install安装整个流程记录(github公有库),完成预期的任务,大致有下面几步: 1.代码提交到github平台 2.创建.podspec 3. ...

  3. 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell

    原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源  本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...

  4. 微软开源PowerShell并支持Linux和OS X

    [微软在开源的道路上加速度了] 从一开始的各种对抗,各种通吃,到现在开始做服务,包罗万象.果然,换了主力,大有不同. 微软今天还宣布开源其.NET框架,令.NET Core能在Linux和OS X上运 ...

  5. 【原创开源】网络版二代双通道示波器开源发布,支持电脑,手机和Pad等各种OS平台访问

    前言感谢大家的支持,提前奉上今年的国庆福利. 一代示波器发布于3年前,去年年底的时候发布了二代示波器,软件性能已经比较强劲,但依然有值得升级改进的地方,经过今年这半年多努力,在二代示波器的基础上再推出 ...

  6. CAT 3.0 开源发布,支持多语言客户端及多项性能提升

    项目背景 CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统.美团点评基础架构部希望在基础存储.高性能通信.大规模在线访问 ...

  7. 微软开源 PowerShell 并支持 Linux 和 OS X

    微软近日宣布开源 PowerShell,开始支持 Linux 和 OSX.PowerShell 是面向 Windows 和 Windows Server 的自动化平台和可扩展脚本语言,可帮助用户简化系 ...

  8. EasyDarwin开源流媒体服务器支持basic基本认证和digest摘要自定义认证

    本文转自EasyDarwin开源团队成员的博客:http://blog.csdn.net/ss00_2012/article/details/52330838 在前面<EasyDarwin拉流支 ...

  9. 阿里云开源镜像站支持IPv6访问

    阿里云开源镜像站在国内企业镜像站中率先支持IPv6访问! 点击立即试用https://developer.aliyun.com/mirror/ 同时基于阿里云OpenSearch的搜索能力,开源镜像站 ...

随机推荐

  1. 不一样的角度 解读微信小程序

    不一样的角度 解读微信小程序 七月在夏天· 2 天前 前段时间看完了雨果奖中短篇获奖小说<北京折叠>.很有意思的是,张小龙最近也要把应用折叠到微信里,这些应用被他称为:小程序. 含着金钥匙 ...

  2. Java中抽象类和接口的区别

    转载自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种 ...

  3. gcc与gdb版本兼容问题

    今天在用gdb调试C++程序的时候,想用"p i”命令打印出程序的一个局部变量i,却一直提示: No symbol "i" in current context. 我愣了 ...

  4. 数据库.bak文件还原报错的处理办法

    今天从网上下了个Demo,里面有个.bak文件,就试着还原了一下,结果发现报了错.是了两种方式导入,都不行. 最终找到了解决办法: 可以直接用sql语句对.bak文件进行还原. RESTORE DAT ...

  5. C# Susan边缘检测(Susan Edge Detection)

    Susan边缘检测,方法简单,效率高,具体参照 The SUSAN Edge Detector in Detail, 修改dThreshold值,可以改变检测效果,用参照提供的重心法.力矩法可得到边缘 ...

  6. webview loadUrl() 弹出系统浏览器解决办法

    有很多时候,我们请求的网站会直接跳转到一个位置,这样会直接全屏浏览器加载被跳转的网页,或者弹出浏览器选择(除了系统的,你还自己安装了其他浏览器). 于是解决办法的原理就是,在webview中跳转. 办 ...

  7. Android观察者模式的简单实现demo

    观察者模式就是:当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新. 下面介绍一种简单的使用方法,(下面有demo链接)先看一下project的目录构成: ObserverList ...

  8. WinForm程序关闭窗体后杀死进程

    调用this.Close();后监听Browser_FormClosed加作处理 this.FormClosed += new System.Windows.Forms.FormClosedEvent ...

  9. Android addHeaderView和setAdapter的调用顺序后报错

    在4.4之前的系统,setAdapter后再设置addHeaderView会爆 ListView想要添加headerview的话,就要通过addHeaderView这个方法,然后想要为ListView ...

  10. ubuntu安装erlang

    照着园子里一篇博文安装erlang,各种错调不出来.最后发现官网有解决方案: https://www.erlang-solutions.com/downloads/download-erlang-ot ...