Compartir a través de


Uso de IAccessibleEx desde un cliente

En este tema se explica cómo los clientes acceden a la implementación de IAccessibleEx de un servidor y lo usan para obtener Automatización de la interfaz de usuario propiedades y patrones de control para los elementos de la interfaz de usuario.

Los procedimientos y ejemplos de esta sección asumen un cliente IAccessible que ya está en proceso y un servidor de accesibilidad activo de Microsoft existente. También asumen que el cliente ya ha obtenido un objeto IAccessible mediante una de las funciones del marco de accesibilidad, como AccessibleObjectFromEvent, AccessibleObjectFromPoint o AccessibleObjectFromWindow.

Obtención de una interfaz IAccessibleEx desde la interfaz IAccessible

Un cliente que tenga una interfaz IAccessible para un objeto accesible puede usarlo para obtener la interfaz IAccessibleEx correspondiente siguiendo estos pasos:

Control del identificador secundario

Los clientes deben estar preparados para servidores con un identificador secundario distinto de CHILDID_SELF. Después de obtener una interfaz IAccessibleEx de un IAccessible, los clientes deben llamar a IAccessibleEx::GetObjectForChild si el identificador secundario no es CHILDID_SELF (lo que indica un objeto primario).

En el ejemplo siguiente se muestra cómo obtener un IAccessibleEx para un objeto IAccessible determinado y un identificador secundario.

   
HRESULT GetIAccessibleExFromIAccessible(IAccessible * pAcc, long idChild, 
                                           IAccessibleEx ** ppaex)
{
    *ppaex = NULL;

    // First, get IServiceProvider from the IAccessible.
    IServiceProvider * pSp = NULL;
    HRESULT hr = pAcc->QueryInterface(IID_IServiceProvider, (void **) & pSp);
    if(FAILED(hr))
        return hr;
    if(pSp == NULL)
        return E_NOINTERFACE;

    // Next, get the IAccessibleEx for the parent object.
    IAccessibleEx * paex = NULL;
    hr = pSp->QueryService(__uuidof(IAccessibleEx), __uuidof(IAccessibleEx),
                                                                 (void **)&paex);
    pSp->Release();
    if(FAILED(hr))
        return hr;
    if(paex == NULL)
        return E_NOINTERFACE;

    // If this is for CHILDID_SELF, we're done. Otherwise, we have a child ID and 
    // can request the object for child.
    if(idChild == CHILDID_SELF)
    {
        *ppaex = paex;
        return S_OK;
    }
    else
    {
        // Get the IAccessibleEx for the specified child.
        IAccessibleEx * paexChild = NULL;
        hr = paex->GetObjectForChild(idChild, &paexChild);
        paex->Release();
        if(FAILED(hr))
            return hr;
        if(paexChild == NULL)
            return E_NOINTERFACE;
        *ppaex = paexChild;
        return S_OK;
    }
}

Obtención de la interfaz IRawElementProviderSimple

Si un cliente tiene una interfaz IAccessibleEx , puede usar QueryInterface para llegar a la interfaz IRawElementProviderSimple , como se muestra en el ejemplo siguiente.

HRESULT GetIRawElementProviderFromIAccessible(IAccessible * pAcc, long idChild,
                                                 IRawElementProviderSimple ** ppEl)
{
    * ppEl = NULL;

    // First, get the IAccessibleEx for the IAccessible and child ID pair.
    IAccessibleEx * paex;
    HRESULT hr = GetIAccessibleExFromIAccessible( pAcc, idChild, &paex );
    if(FAILED(hr))
        return hr;

    // Next, use QueryInterface.
    hr = paex->QueryInterface(__uuidof(IRawElementProviderSimple), (void **)ppEl);
    paex->Release();
    return hr;
}

Recuperación de patrones de control

Si un cliente tiene acceso a la interfaz IRawElementProviderSimple , puede recuperar interfaces de patrón de control implementadas por proveedores y, a continuación, llamar a métodos en esas interfaces. El ejemplo siguiente muestra cómo hacerlo.

// Helper function to get a pattern interface from an IAccessible and child ID 
// pair. Gets the IAccessibleEx, then calls GetPatternObject and QueryInterface.
HRESULT GetPatternFromIAccessible(IAccessible * pAcc, long idChild,
                                     PATTERNID patternId, REFIID iid, void ** ppv)
{
    // First, get the IAccesibleEx for this IAccessible and child ID pair.
    IRawElementProviderSimple * pel;
    HRESULT hr = GetIRawElementProviderSimpleFromIAccessible(pAcc, idChild, &pel);
    if(FAILED(hr))
        return hr;
    if(pel == NULL)
        return E_NOINTERFACE;

    // Now get the pattern object.
    IUnknown * pPatternObject = NULL;
    hr = pel->GetPatternProvider(patternId, &pPatternObject);
    pel->Release();
    if(FAILED(hr))
        return hr;
    if(pPatternObject == NULL)
        return E_NOINTERFACE;

    // Finally, use QueryInterface to get the correct interface type.
    hr = pPatternObject->QueryInterface(iid, ppv);
    pPatternObject->Release();
    if(*ppv == NULL)
        return E_NOINTERFACE;
    return hr;
}

HRESULT CallInvokePatternMethod(IAccessible * pAcc, long idChild)
{
    IInvokeProvider * pPattern;
    HRESULT hr = GetPatternFromIAccessible(pAcc, varChild,
                                  UIA_InvokePatternId, __uuidof(IInvokeProvider),
                                  (void **)&pPattern);
    if(FAILED(hr))
        return hr;

    hr = pPattern->Invoke();
    pPattern->Release();
    return hr;
}

Recuperar valores de propiedad

Si un cliente tiene acceso a IRawElementProviderSimple, puede recuperar los valores de propiedad. En el ejemplo siguiente se muestra cómo obtener valores para las propiedades AutomationId y LabeledBy microsoft Automatización de la interfaz de usuario.

#include <initguid.h>
#include <uiautomationcoreapi.h> // Includes the UI Automation property GUID definitions.
#include <uiautomationcoreids.h> // Includes definitions of pattern/property IDs.

// Assume we already have a IRawElementProviderSimple * pEl.

VARIANT varValue;

// Get AutomationId property:
varValue.vt = VT_EMPTY;
HRESULT hr = pEl->GetPropertyValue(UIA_AutomationIdPropertyId, &varValue);
if(SUCCEEDED(hr))
{
    if(varValue.vt == VT_BSTR)
    {
        // AutomationId is varValue.bstrVal.
    }
    VariantClear(&varValue);
}


// Get LabeledBy property:
varValue.vt = VT_EMPTY;
hr = pEl->GetPropertyValue(UIA_LabeledByPropertyId, &varValue);
if(SUCCEEDED(hr))
{
    if(varValue.vt == VT_UNKNOWN || varValue.punkVal != NULL)
    {
        // Use QueryInterface to get IRawElementProviderSimple.
        IRawElementProviderSimple * pElLabel = NULL;
        hr = varValue.punkVal->QueryInterface(__uuidof(IRawElementProviderSimple),
                                              (void**)& pElLabel);
        if (SUCCEEDED(hr))
        {
            if(pElLabel != NULL)
            {
            // Use the pElLabel pointer here.
            pElLabel ->Release();
            }
        }
    }
    VariantClear(&varValue);
}

El ejemplo anterior se aplica a las propiedades que no están asociadas a un patrón de control. Para obtener acceso a las propiedades del patrón de control, un cliente debe obtener y usar una interfaz de patrón de control.

Recuperar una interfaz IAccessible desde una interfaz IRawElementProviderSimple

Si un cliente obtiene la interfaz IRawElementProviderSimple de un elemento de interfaz de usuario, el cliente puede usar esa interfaz para obtener una interfaz IAccessible correspondiente para el elemento. Esto resulta útil si el cliente necesita acceder a las propiedades de accesibilidad activa de Microsoft para el elemento .

Un cliente puede obtener la interfaz IRawElementProviderSimple como un valor de propiedad (por ejemplo, llamando a IRawElementProviderSimple::GetPropertyValue con UIA_LabeledByPropertyId) o como un elemento recuperado por un método (por ejemplo, llamando a ISelectionProvider::GetSelection para recuperar una matriz de interfaces IRawElementProviderSimple de los elementos seleccionados). Después de obtener la interfaz IRawElementProviderSimple , un cliente puede usarlo para obtener un IAccessible correspondiente siguiendo estos pasos:

El siguiente fragmento de código muestra cómo obtener la interfaz IAccessible de una interfaz IRawElementProviderSimple obtenida previamente.

// IRawElementProviderSimple * pVal - an element returned by a property or method
// from another IRawElementProviderSimple.

IAccessible * pAcc = NULL;
long idChild;

// First, try to use QueryInterface to get the IAccessibleEx interface.
IAccessibleEx * pAccEx;
HRESULT hr = pVal->QueryInterface(__uuidof(IAccessibleEx), (void**)&pAccEx);
if (SUCCEEDED(hr)
{
    if (!pAccEx)
    {
        // If QueryInterface fails, and the IRawElementProviderSimple was 
              // obtained as a property or return value from another 
              // IRawElementProviderSimple, pass it to the 
              // IAccessibleEx::ConvertReturnedValue method of the
        // originating element.

        pAccExOrig->ConvertReturnedElement(pVal, &pAccEx);
    }

    if (pAccEx)
    {
        // Call GetIAccessiblePair to get an IAccessible interface and 
              // child ID.
        pAccEx->GetIAccessiblePair(&pAcc, &idChild);
    }

    // Finally, use the IAccessible interface and child ID.
    if (pAcc)
    {
        // Use IAccessible methods to get further information about this UI
              // element, or pass it to existing code that works in terms of 
              // IAccessible.
        ...
    }
}