Share via


Adición de Automatización de la interfaz de usuario funcionalidad a servidores de accesibilidad activos

Los controles que no tienen un proveedor de Microsoft Automatización de la interfaz de usuario, pero que implementan IAccessible se pueden actualizar fácilmente para proporcionar algunas funciones de Automatización de la interfaz de usuario mediante la implementación de la interfaz IAccessibleEx. Esta interfaz permite que el control exponga Automatización de la interfaz de usuario propiedades y patrones de control, sin necesidad de una implementación completa de Automatización de la interfaz de usuario interfaces de proveedor como IRawElementProviderFragment. Para implementar IAccessibleEx, la jerarquía de objetos de accesibilidad activa de Microsoft de línea base no debe contener errores ni incoherencias (por ejemplo, un objeto secundario cuyo objeto primario no lo enumera como elemento secundario) y no debe entrar en conflicto con las especificaciones de Automatización de la interfaz de usuario. Si la jerarquía de objetos de accesibilidad activa de Microsoft cumple estos requisitos, es un buen candidato para agregar funcionalidad mediante IAccessibleEx; de lo contrario, debe implementar Automatización de la interfaz de usuario solo o junto con la implementación de accesibilidad activa de Microsoft.

Tome el caso de un control personalizado que tenga un valor de intervalo. El servidor de accesibilidad activa de Microsoft para el control define su rol y puede devolver su valor actual, pero carece de los medios para devolver los valores mínimos y máximos del control, ya que estas propiedades no están definidas en Accesibilidad activa de Microsoft. Un cliente Automatización de la interfaz de usuario puede recuperar el rol del control, el valor actual y otras propiedades de accesibilidad activa de Microsoft, ya que el Automatización de la interfaz de usuario núcleo puede obtenerlos a través de IAccessible. Sin embargo, sin acceso a una interfaz IRangeValueProvider en el objeto, Automatización de la interfaz de usuario tampoco puede recuperar los valores máximos y mínimos.

El desarrollador de controles podría proporcionar un proveedor completo de Automatización de la interfaz de usuario para el control, pero esto significaría duplicar gran parte de la funcionalidad existente de la implementación de IAccessible: por ejemplo, la navegación y las propiedades comunes. En su lugar, el desarrollador puede seguir confiando en IAccessible para proporcionar esta funcionalidad, al tiempo que agrega compatibilidad con propiedades específicas del control a través de IRangeValueProvider.

La actualización del control personalizado requiere estos pasos principales:

  • Implemente IServiceProvider en el objeto accesible para que la interfaz IAccessibleEx se pueda encontrar en este objeto o en un objeto independiente.
  • Implemente IAccessibleEx en el objeto accesible.
  • Cree objetos accesibles distintos para cualquier elemento secundario de accesibilidad activa de Microsoft, que en Accesibilidad activa de Microsoft podría haber sido representado por la interfaz IAccessible en el objeto primario (por ejemplo, elementos de lista). Implemente IAccessibleEx en estos objetos.
  • Implemente IRawElementProviderSimple en todos los objetos accesibles.
  • Implemente las interfaces de patrón de control adecuadas en los objetos accesibles.

En este tema se incluyen las siguientes secciones.

Exposición de IAccessibleEx

Dado que la implementación de IAccessibleEx para un control puede residir en un objeto independiente, las aplicaciones cliente no pueden depender de QueryInterface para obtener esta interfaz. En su lugar, se espera que los clientes llamen a IServiceProvider::QueryService. En la siguiente implementación de ejemplo de este método, se supone que IAccessibleEx no se implementa en un objeto independiente; por lo tanto, el método simplemente llama a a QueryInterface.

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;
    }
};

Implementación de IAccessibleEx

El método de IAccessibleEx que es de mayor interés es GetObjectForChild. Este método ofrece al servidor de accesibilidad activa de Microsoft la oportunidad de crear un objeto accesible (uno que expone, como mínimo, IAccessibleEx) para un elemento secundario. En Accesibilidad activa de Microsoft, los elementos secundarios normalmente no se representan como objetos accesibles, sino como elementos secundarios de un objeto accesible. Sin embargo, dado que Automatización de la interfaz de usuario requiere que cada elemento esté representado por un objeto accesible independiente, GetObjectForChild debe crear un objeto independiente para cada elemento secundario a petición.

La siguiente implementación de ejemplo devuelve un objeto accesible para un elemento de una vista de lista personalizada.

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; 
}

Para obtener una implementación de ejemplo completa, vea Hacer que los controles personalizados sean accesibles, parte 5: Usar IAccessibleEx para agregar Automatización de la interfaz de usuario compatibilidad con un control personalizado en MSDN.

Guía del programador del proveedor de Automatización de la interfaz de usuario