一、前言

我们知道,正常人操作电脑,只需一眼便能得知屏幕上的内容,要想激活某个控件,例如按钮等,只需将鼠标拖动过去点击即可。

但这对于盲人而言,却十分繁琐。

盲人使用屏幕阅读器来操作电脑,在使用某个软件时,会使用Tab键进行浏览,每按下一次Tab键,就会将当前焦点移动到下一个控件,同时语音会朗读出其标签等信息。如果想浏览上一个控件,则可以使用Shift+Tab键,进行反向浏览。

因此,可以说盲人就是靠着Tab键浏览软件界面的。然而,屏幕阅读器并不支持Tab键浏览,而是需要软件本身支持。

为了让软件更好地做到无障碍,下面我来介绍一下,用C/C++写的应用应该如何支持Tab键浏览。

二、实现原理

支持Tab键浏览的原理,其实就是在窗口的消息处理函数中处理Tab键、Shift+Tab键的按下消息。

例如,可以使用如下代码:

switch (message)
{
// 判断是按键按下消息
case WM_KEYDOWN:
switch (wParam)
{
// 判断按键为tab键
case VK_TAB:
// 判断是否同时按下shift键
if (GetKeyState(VK_SHIFT) < 0)
// 此处将焦点移动到上一个控件,实现反向浏览
else
// 此处将焦点移动到下一个控件,实现正序浏览
return 0;
}
break;
}

得知原理后,我们就可以开始处理焦点移动了。

不过此处还分为两种情况:

1.每个控件都有单独窗口句柄

如果是此种情况,则可以直接调用SetFocus函数,将下一个或上一个控件的窗口句柄传入,及会将焦点移动过去。

如果为了方便起见,我们还可以使用GetWindow函数,传入GW_HWNDPREV标识,返回值为上一个同层级控件的句柄,也可以传入GW_HWNDLAST获取出最后一个控件、GW_HWNDNEXT下一个控件、GW_HWNDFIRST第一个控件。

2.控件都无单独窗口句柄

此种情况一般只有最外层的容器存在窗口句柄,所以就无法使用SetFocus函数来进行焦点的移动了。

我们需要调用NotifyWinEvent函数,来通知焦点的变化,函数原型如下:

void NotifyWinEvent(DWORD event,HWND  hwnd,LONG  idObject,LONG  idChild
);

第一个参数为事件类型
此处我们使用EVENT_OBJECT_FOCUS表示的是焦点变化事件。

第二个参数为窗口句柄

第三个为触发事件的对象ID

一般我们直接传入OBJID_CLIENT即可。

第四个为此事件是对象本身触发,还是其子控件触发

要实现焦点的浏览,我们主要就是靠第四个参数,用它来标明当前浏览到了哪一个控件。

首先我们内部需要给每个控件都设置一个独立的ID,而当触发焦点变化事件的时候,就将此ID传入第四个参数。

当然,仅仅这样是不够的,我们还需要让容器窗口实现IAccessible接口,在get_accName、get_accRole等方法中根据varChild的lVal属性,去返回相对应控件的标签、类型等。

至于具体怎么实现,可参考之前的文章:

C++中给控件设置标签的方法 - 蔡勇斌的文章 - 知乎 https://zhuanlan.zhihu.com/p/159173668

三、后续

虽然让软件支持无障碍需要一定的工作量,但是,就是因为有了无障碍的存在,才能让无数残疾人可以平等的享受科技带来的便利。

愿无障碍可以加入到每一款软件的开发流程中。开发多一点,障碍少一点!

tab键怎么关闭_C/C++应用无障碍化如何支持Tab键浏览相关推荐

  1. 怎么把一个控件放到tab页面上去?_C/C++应用无障碍化如何支持Tab键浏览

    一.前言 我们知道,正常人操作电脑,只需一眼便能得知屏幕上的内容,要想激活某个控件,例如按钮等,只需将鼠标拖动过去点击即可. 但这对于盲人而言,却十分繁琐. 盲人使用屏幕阅读器来操作电脑,在使用某个软 ...

  2. sqlplus 主键 设置_浅谈MyBatis-Plus学习之Oracle的主键Sequence设置

    一.Oracle的主键Sequence设置简介 在Oracle数据库中不支持主键自增策略,它是通过Sequence序列来进行完成的,因此需要在MP中进行相关配置 二.相关配置如下 2.1.pom.xm ...

  3. html文本框打tab,HTML标签textarea支持tab键

    码农很需要的,让textarea支持tab键 HTML #require void main() { printf("hello world!\n"); } jQuery $(&q ...

  4. win10关机后cpu风扇还在转_win10关机后风扇一直转,长按电源键才关闭怎么办

    最近有朋友问小编win10关机后风扇一直转,长按电源键才关闭怎么办,关于这个问题,相信还有很多朋友不明白,为什么win10关机后风扇一直转,需要我们长按电源键才关闭呢?遇到这种关机风扇还转的情况要如何 ...

  5. 如何取消shift粘滞键?Win11粘滞键彻底关闭的方法

    ​Windows中的粘滞键是专为同时按下两个或多个键有困难的人设计的.粘滞键的主要功能是方便Shift.Ctrl.Alt与其他键的组合使用.在我们使用热键,例如"CTRL+C"时, ...

  6. Linux Centos8最小化安装,tab键无法使用解决方法

    最小化安装,tab键无法使用解决方法 安装bash-completione,可能会遇到下图情况 [root@zjq ~]# yum -y install bash-completion CentOS ...

  7. layer的tab添加html,layerui代码控制tab选项卡,添加,关闭的实例

    layui layui 后台布局 控制台 商品管理 用户 其它系统 邮件管理 消息管理 授权管理 贤心 基本资料 安全设置 退了 所有商品 列表一 列表二 列表三 超链接 解决方案 列表一 列表二 超 ...

  8. iOS平台无障碍化利器——VoiceOver

    作者: 王哲(debug),腾讯实习生,现就读于吉林大学.2016年实习于腾讯公司,主要从事iPhone手机QQ无障碍化相关的技术预研,包括声纹转换等. 闫石(rockey),腾讯移动客户端开发高级工 ...

  9. 客制化机械键盘改键软件VIA介绍

    VIA可以汉化,也可以直接使用原版本.如果汉化,就会失去via里很有意思的一个功能--any键.接下来以原版本对via功能进行大概介绍. 要使用via,请确保你的键盘支持via改键,且有对应键盘的.j ...

最新文章

  1. 反卷积(Transposed Convolution, Fractionally Strided Convolution or Deconvolution)
  2. 《Apache Common CLI官方文档
  3. BZOJ1217: [HNOI2003]消防局的设立
  4. 【python初识】列表与函数模块
  5. Servlet 全局验证是否登录
  6. oracle逻辑备份和物理备份,oracle数据库物理备份和逻辑备份区别
  7. Android初级教程获取手机系统联系人信息
  8. c语言程序找出500以内的所有素数,c语言求出给定范围内的所有质数
  9. ASP.NET Core 1.0 开发记录
  10. 结队编程项目——四则运算
  11. python嵌套列表操作_python基础(list列表的操作,公共方法,列表嵌套,元祖)...
  12. 【SSM面向CRUD编程专栏 2】Spring相关API 数据源(连接池)的配置 注解开发 整合junit
  13. ElementUI+Java实现搜索提示列表
  14. pymysql安装_centos7.6 安装openstack stein组件之四
  15. jvm 的内存分配方式
  16. SVN创建分支与分支合并主干
  17. 计算机科学与技术总体培养目标,计算机科学与技术专业培养目标
  18. windowsxp下载python下载视频_Python实现视频下载功能
  19. 图像处理算法工程师必备技能总结
  20. Help Hanzo LightOJ - 1197

热门文章

  1. 你知道K8S暴露服务的方式有哪些吗?
  2. Spring Security:自定义登录页面
  3. 超级详细的手写webpack4配置来启动vue2项目(附配置作用)
  4. vue苹果浏览器微信公众号底部回退栏如何固定或隐藏
  5. [DeeplearningAI笔记]序列模型3.2有条件的语言模型与贪心搜索的不可行性
  6. golang解析IP到城市jsonRPC服务教程
  7. 服务端架构设计及功能说明-续1
  8. (转)oracle审计详解
  9. Cygwin 的代理设置(同 Linux)
  10. 动态链接库实现COM(COM技术内幕笔记之二)