Usando IAccessibleEx de um cliente

Este tópico explica como os clientes acessam a implementação IAccessibleEx de um servidor e a usam para obter Automação da Interface do Usuário propriedades e padrões de controle para elementos de interface do usuário.

Os procedimentos e exemplos nesta seção pressupõem um cliente IAccessible que já está em processo e um servidor microsoft active accessibility existente. Eles também pressupõem que o cliente já obteve um objeto IAccessible usando uma das funções da estrutura de acessibilidade, como AccessibleObjectFromEvent, AccessibleObjectFromPoint ou AccessibleObjectFromWindow.

Obtendo uma interface IAccessibleEx da interface IAccessible

Um cliente que tem uma interface IAccessible para um objeto acessível pode usá-lo para obter a interface IAccessibleEx correspondente seguindo estas etapas:

Manipulando a ID filho

Os clientes devem estar preparados para servidores com uma ID filho diferente de CHILDID_SELF. Depois de obter uma interface IAccessibleEx de um IAccessible, os clientes deverão chamar IAccessibleEx::GetObjectForChild se a ID filho não estiver CHILDID_SELF (indicando um objeto pai).

O exemplo a seguir mostra como obter um IAccessibleEx para um objeto IAccessible específico e uma ID filho.

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

Obtendo a interface IRawElementProviderSimple

Se um cliente tiver uma interface IAccessibleEx , ele poderá usar QueryInterface para acessar a interface IRawElementProviderSimple , como mostra o exemplo a seguir.

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

Recuperando padrões de controle

Se um cliente tiver acesso à interface IRawElementProviderSimple , ele poderá recuperar interfaces de padrão de controle que foram implementadas por provedores e, em seguida, poderá chamar métodos nessas interfaces. O exemplo a seguir mostra como fazer isso.

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

Recuperando valores de propriedade

Se um cliente tiver acesso a IRawElementProviderSimple, ele poderá recuperar valores de propriedade. O exemplo a seguir mostra como obter valores para as propriedades AutomationId e LabeledBy microsoft Automação da Interface do Usuário.

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

O exemplo anterior se aplica a propriedades que não estão associadas a um padrão de controle. Para acessar propriedades de padrão de controle, um cliente deve obter e usar uma interface de padrão de controle.

Recuperando uma interface IAccessible de uma interface IRawElementProviderSimple

Se um cliente obtiver a interface IRawElementProviderSimple para um elemento de interface do usuário, o cliente poderá usar essa interface para obter uma interface IAccessible correspondente para o elemento. Isso será útil se o cliente precisar acessar as propriedades de Acessibilidade Ativa da Microsoft para o elemento .

Um cliente pode obter a interface IRawElementProviderSimple como um valor de propriedade (por exemplo, chamando IRawElementProviderSimple::GetPropertyValue com UIA_LabeledByPropertyId) ou como um item recuperado por um método (por exemplo, chamando ISelectionProvider::GetSelection para recuperar uma matriz de interfaces IRawElementProviderSimple de elementos selecionados). Depois de obter a interface IRawElementProviderSimple , um cliente pode usá-la para obter um IAccessible correspondente seguindo estas etapas:

O snippet de código a seguir demonstra como obter a interface IAccessible de uma interface IRawElementProviderSimple obtida anteriormente.

// 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.
        ...
    }
}