13

我想从头开始实现一个支持 IAccessible 接口的文本编辑器。我正在使用 MFC 和 Win32 API。

当记事本等标准文本编辑器中的插入符号位置发生变化时,插入符号移动的相应字母、单词或行由讲述人、JAWS 等客户端工具发音。我不知道如何实现此功能。我搜索互联网并阅读 MSDN 文档。

我在http://msdn.microsoft.com/en-us/library/dd317978.aspxhttp://msdn.microsoft.com/en-us/library/dd373892.aspx中读到客户端通过 AccessibleObjectFromWindow 方法请求插入符号从操作系统,操作系统发送 WM_GETOBJECT 到应用程序。WM_GETOBJECT 消息在相应的窗口回调函数中收到,但对于插入符号移动事件的 hWnd 为 NULL。我检查了线程消息队列,但是线程消息队列中根本没有收到 WM_GETOBJECT。

一种有效但不是正确解决方案的方法是调用

NotifyWinEvent( EVENT_OBJECT_NAMECHANGE, hwnd, OBJID_CLIENT, CHILDID_SELF )

当插入符号被用户移动时。当客户要求更改名称时,我返回与插入符号移动相关的相应文本。

HRESULT  CMyEditor::get_accName(VARIANT varChild, BSTR *pszName)
{
   *pszName = SysAllocString( L"CORESPONDING TEXT TO THE CARET MOVEMENT" );
   return S_OK;
}
4

1 回答 1

6

客户端将使用SetWinEventHook()函数来跟踪插入符号的以下事件:

  • EVENT_OBJECT_CREATE
  • EVENT_OBJECT_DESTROY
  • EVENT_OBJECT_SHOW
  • EVENT_OBJECT_HIDE
  • EVENT_OBJECT_LOCATIONCHANGE
  • EVENT_OBJECT_FOCUS

如果您使用自定义控件,则需要使用NotifyWinEvent()自己触发这些事件,尤其是应该触发旁白的 EVENT_OBJECT_LOCATIONCHANGE。

当客户端处理这些事件时,它应该使用AccessibleObjectFromEvent() 访问他正在跟踪的对象的IAccessible接口。

正如您所说,Microsoft Active Accessibility 将处理此调用并将 WM_GETOBJECT 消息发送到相应的窗口,具体取决于提供给AccessibleObjectFromEvent()的处理程序(应该是事件中包含的处理程序)。

当您收到插入符号的 WM_GETOBJECT 时,您应该返回相应的IAccessible接口,该接口将报告正确的accRoleaccLocation

如果您没有收到正确的 WM_GETOBJECT 消息,可能是因为您没有触发正确的事件。

您可以使用Accessible Event Watcher检查是否发送了正确的事件:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd317979%28v=vs.85%29.aspx

请参阅 MSDN 上的 Active Accessibility Servers 开发人员指南:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd318053%28v=vs.85%29.aspx

编辑

此外,如果您使用 Riched20.dll 提供的标准插入符号(在 Rich Edit 中作为实例),文档规定与其他 UI 元素不同,它没有关联的窗口句柄。

于 2013-04-10T12:34:52.320 回答