What is the correct solution to support IAccesible interface for caret movement in text editors?

陌路散爱 提交于 2019-12-04 16:58:22

问题


I want to implement a text editor from scratch which supports IAccessible interface. I am using MFC and Win32 API.

When the caret position change in the standard text editors like Notepad, the corresponding letter, word or line to the caret movement is pronounced by client tools like Narrator, JAWS or etc. I don't know how to implement this feature. I search the internet and read the MSDN documentation.

I read in http://msdn.microsoft.com/en-us/library/dd317978.aspx and http://msdn.microsoft.com/en-us/library/dd373892.aspx that client asks for caret by AccessibleObjectFromWindow method from OS, and OS send WM_GETOBJECT to the application. WM_GETOBJECT messages received in the corresponding window callback function, but hWnd for caret movement event is NULL. I checked the thread message queue, but WM_GETOBJECT didn't receive at all in the thread message queue.

One method that has worked somewhat, but not the correct solution is to call

NotifyWinEvent( EVENT_OBJECT_NAMECHANGE, hwnd, OBJID_CLIENT, CHILDID_SELF )

when the caret move by user. And when client ask for the changed name, I return the corresponding text related to the caret movement.

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

回答1:


The client would use the SetWinEventHook() function to track the following events of the caret :

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

If you use a custom control, you need to use NotifyWinEvent() to fire those events yourself, especially EVENT_OBJECT_LOCATIONCHANGE which should trigger the narration.

When the client handle thoses events, it should access the IAccessible interface of the object he's tracking using AccessibleObjectFromEvent().

As you say, Microsoft Active Accessibility would handle this call and send an WM_GETOBJECT message to the corresponding window depending on the handler given to AccessibleObjectFromEvent() (which should be the handler contained in the event).

When you receive the WM_GETOBJECT for the caret you should return the corresponding IAccessible interface which would report the proper accRole and accLocation.

If you're not receiving the right WM_GETOBJECT message it may be because you're not triggering the right events.

You can use the Accessible Event Watcher to check if the right events are sent : http://msdn.microsoft.com/en-us/library/windows/desktop/dd317979%28v=vs.85%29.aspx

See the Developer's Guide for Active Accessibility Servers on MSDN : http://msdn.microsoft.com/en-us/library/windows/desktop/dd318053%28v=vs.85%29.aspx

Edit

Also, if you're using the standard caret provided by Riched20.dll (in a Rich Edit as instance), the documentation stipulate that unlike other UI elements, it does not have an associated window handle.



来源:https://stackoverflow.com/questions/15689006/what-is-the-correct-solution-to-support-iaccesible-interface-for-caret-movement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!