Поделиться через


Добавление функций модель автоматизации пользовательского интерфейса на активные серверы специальных возможностей

Элементы управления, у которых нет поставщика microsoft модель автоматизации пользовательского интерфейса, но реализующие I Access можно легко обновить, чтобы предоставить некоторые модель автоматизации пользовательского интерфейса функциональные возможности, реализуя интерфейс IAccessibleEx. Этот интерфейс позволяет элементу управления предоставлять модель автоматизации пользовательского интерфейса свойства и шаблоны элементов управления без полной реализации интерфейсов поставщика модель автоматизации пользовательского интерфейса, таких как IRawElementProviderFragment. Чтобы реализовать IAccessibleEx, базовая иерархия объектов Microsoft Active Accessibility не должна содержать ошибок или несоответствий (например, дочерний объект, родительский объект которого не перечисляет его как дочерний), и не должен конфликтовать с спецификациями модель автоматизации пользовательского интерфейса. Если иерархия объектов Microsoft Active Accessibility соответствует этим требованиям, это хороший кандидат для добавления функциональных возможностей с помощью IAccessibleEx; в противном случае необходимо реализовать модель автоматизации пользовательского интерфейса только или вместе с реализацией microsoft Active Accessibility.

Рассмотрим случай пользовательского элемента управления, имеющего значение диапазона. Сервер Microsoft Active Accessibility для элемента управления определяет свою роль и может возвращать текущее значение, но не имеет средств для возврата минимальных и максимальных значений элемента управления, так как эти свойства не определены в Microsoft Active Accessibility. Клиент модель автоматизации пользовательского интерфейса может получить роль элемента управления, текущее значение и другие свойства специальных возможностей Microsoft Active, так как ядро модель автоматизации пользовательского интерфейса может получить их с помощью I Access. Однако без доступа к интерфейсу IRangeValueProvider в объекте модель автоматизации пользовательского интерфейса также не удается получить максимальные и минимальные значения.

Разработчик элементов управления может предоставить полный поставщик модель автоматизации пользовательского интерфейса для элемента управления, но это будет означать дублирование большей части существующих функциональных возможностей реализации IAccessible: например, навигации и общих свойств. Вместо этого разработчик может продолжать полагаться на IAccessible для предоставления этой функции, добавляя поддержку свойств для определенных элементов управления через IRangeValueProvider.

Для обновления пользовательского элемента управления требуются следующие основные действия.

  • Реализуйте IServiceProvider в объекте со специальными возможностями, чтобы интерфейс IAccessibleEx можно было найти в этом или отдельном объекте.
  • Реализуйте IAccessibleEx в объекте со специальными возможностями.
  • Создайте отдельные объекты со специальными возможностями для всех дочерних элементов Microsoft Active Accessibility, которые, возможно, были представлены интерфейсом I Access в родительском объекте (например, элементы списка). Реализуйте IAccessibleEx для этих объектов.
  • Реализуйте IRawElementProviderSimple для всех доступных объектов.
  • Реализуйте соответствующие интерфейсы шаблонов управления на доступных объектах.

Эта тема описана в следующих разделах.

Предоставление доступа iAccessibleEx

Так как реализация IAccessibleEx для элемента управления может находиться в отдельном объекте, клиентские приложения не могут полагаться на QueryInterface для получения этого интерфейса. Вместо этого клиенты должны вызывать IServiceProvider::QueryService. В следующем примере реализации этого метода предполагается, что IAccessibleEx не реализован в отдельном объекте, поэтому метод просто вызывает запросInterface.

HRESULT CListboxAccessibleObject::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
{
    if (!ppvObject)
    {
        return E_INVALIDARG;
    }
    *ppvObject = NULL;
    if (guidService == __uuidof(IAccessibleEx))
    {
        return QueryInterface(riid, ppvObject);
    }
    else 
    {
        return E_INVALIDARG;
    }
};

Реализация IAccessibleEx

Метод IAccessibleEx, который наиболее интересен, является GetObjectForChild. Этот метод предоставляет серверу Microsoft Active Accessibility возможность создать доступный объект (который предоставляет как минимум IAccessibleEx) для дочернего элемента. В Microsoft Active Accessibility дочерние элементы обычно не представляются как доступные объекты, а как дочерние объекты. Однако, поскольку модель автоматизации пользовательского интерфейса требует, чтобы каждый элемент был представлен отдельным доступным объектом, GetObjectForChild должен создать отдельный объект для каждого дочернего элемента по запросу.

В следующем примере реализации возвращается доступный объект для элемента в пользовательском представлении списка.

HRESULT CListboxAccessibleObject::GetObjectForChild(long idChild, IAccessibleEx **pRetVal)
{ 
    *pRetVal = NULL;
    VARIANT vChild;
    vChild.vt = VT_I4;
    vChild.lVal = idChild;

    // ValidateChildId is an application-defined function that checks whether
    // the child ID is valid. This is similar to code that validates the varChild
    // parameter in IAccessible methods.
    //
    // Additionally, if this idChild corresponds to a child that has its own
    // IAccessible, we should also return E_INVALIDARG here. (The caller
    // should instead be using the IAccessibleEx from that child's own
    // IAccessible in that case.)
    if (idChild == CHILDID_SELF || FAILED(ValidateChildId(vChild)))
    {
        return E_INVALIDARG;
    }

    // Return a suitable provider for this specific child.
    // This implementation returns a new instance each time; an implementation
    // can cache these if desired.

    // _pListboxControl is a member variable pointer to the owning control.
    IAccessibleEx* pAccEx  = new CListItemAccessibleObject(idChild, _pListboxControl);
    if (pAccEx == NULL)
    {
        return E_OUTOFMEMORY;
    }
    *pRetVal = pAccEx;
    return S_OK; 
}

Полный пример реализации см. в статье "Создание специальных элементов управления", часть 5. Использование IAccessibleEx для добавления модель автоматизации пользовательского интерфейса поддержки в пользовательский элемент управления.

Руководство программиста поставщика модель автоматизации пользовательского интерфейса