Какое правильное решение поддерживает интерфейс IAccesible для перемещения каретки в текстовых редакторах?
Я хочу реализовать текстовый редактор с нуля, который поддерживает интерфейс IAccessible. Я использую MFC и Win32 API.
Когда позиция каретки изменяется в стандартных текстовых редакторах, таких как Блокнот, соответствующая буква, слово или строка движения каретки произносится такими инструментами клиента, как Рассказчик, JAWS и т. Д. Я не знаю, как реализовать эту функцию. Я ищу в Интернете и читаю документацию MSDN.
Я прочитал в http://msdn.microsoft.com/en-us/library/dd317978.aspx и http://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;
}
1 ответ
Клиент будет использовать функцию SetWinEventHook() для отслеживания следующих событий каретки:
- EVENT_OBJECT_CREATE
- EVENT_OBJECT_DESTROY
- EVENT_OBJECT_SHOW
- EVENT_OBJECT_HIDE
- EVENT_OBJECT_LOCATIONCHANGE
- EVENT_OBJECT_FOCUS
Если вы используете пользовательский элемент управления, вам нужно использовать NotifyWinEvent() для запуска этих событий самостоятельно, особенно EVENT_OBJECT_LOCATIONCHANGE, которая должна вызвать повествование.
Когда клиент обрабатывает события, он должен получить доступ к интерфейсу IAccessible объекта, который он отслеживает, с помощью AccessibleObjectFromEvent ().
Как вы говорите, Microsoft Active Accessibility обработает этот вызов и отправит сообщение WM_GETOBJECT в соответствующее окно в зависимости от обработчика, данного AccessibleObjectFromEvent () (который должен быть обработчиком, содержащимся в событии).
Когда вы получите WM_GETOBJECT для каретки, вы должны вернуть соответствующий интерфейс IAccessible, который сообщит о правильном accRole и accLocation.
Если вы не получаете правильное сообщение WM_GETOBJECT, это может быть потому, что вы не запускаете правильные события.
Вы можете использовать Accessible Event Watcher, чтобы проверить, правильно ли отправляются события: http://msdn.microsoft.com/en-us/library/windows/desktop/dd317979%28v=vs.85%29.aspx
См. Руководство разработчика для серверов активной доступности на MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318053%28v=vs.85%29.aspx
редактировать
Кроме того, если вы используете стандартную каретку, предоставленную Riched20.dll (например, в Rich Edit), в документации предусмотрено, что в отличие от других элементов пользовательского интерфейса, он не имеет ассоциированного дескриптора окна.