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

d3379e87bcf57a5fb0fe89d7e076c1e5.png

一、前言

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

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

盲人使用屏幕阅读器来操作电脑,在使用某个软件时,会使用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

三、后续

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值