Share via


클라이언트에서 IAccessibleEx 사용

이 항목에서는 클라이언트가 서버의 IAccessibleEx 구현에 액세스하고 이를 사용하여 UI 요소에 대한 UI 자동화 속성 및 컨트롤 패턴을 가져오는 방법을 설명합니다.

이 섹션의 절차 및 예제에서는 이미 처리 중인 IAccessible 클라이언트와 기존 Microsoft Active Accessibility 서버를 가정합니다. 또한 클라이언트가 AccessibleObjectFromEvent, AccessibleObjectFromPoint 또는 AccessibleObjectFromWindow와 같은 접근성 프레임워크 함수 중 하나를 사용하여 IAccessible 개체를 이미 획득했다고 가정합니다.

IAccessible 인터페이스에서 IAccessibleEx 인터페이스 가져오기

액세스 가능한 개체에 대한 IAccessible 인터페이스가 있는 클라이언트는 이 인터페이스를 사용하여 다음 단계에 따라 해당 IAccessibleEx 인터페이스를 가져올 수 있습니다.

자식 ID 처리

클라이언트는 CHILDID_SELF 이외의 자식 ID가 있는 서버에 대해 준비해야 합니다. IAccessible에서 IAccessibleEx 인터페이스를 가져온 후 자식 ID가 CHILDID_SELF 않은 경우(부모 개체를 나타낸) 클라이언트는 IAccessibleEx::GetObjectForChild를 호출해야 합니다.

다음 예제에서는 특정 IAccessible 개체 및 자식 ID에 대한 IAccessibleEx를 가져오는 방법을 보여 줍니다.

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

IRawElementProviderSimple 인터페이스 가져오기

클라이언트에 IAccessibleEx 인터페이스가 있는 경우 다음 예제와 같이 QueryInterface를 사용하여 IRawElementProviderSimple 인터페이스에 액세스할 수 있습니다.

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

컨트롤 패턴 검색

클라이언트가 IRawElementProviderSimple 인터페이스에 액세스할 수 있는 경우 공급자가 구현한 컨트롤 패턴 인터페이스를 검색한 다음 해당 인터페이스에서 메서드를 호출할 수 있습니다. 다음 예제에 이 작업을 수행하는 방법이 나와 있습니다.

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

속성 값 검색

클라이언트가 IRawElementProviderSimple에 액세스할 수 있는 경우 속성 값을 검색할 수 있습니다. 다음 예제에서는 AutomationId 및 LabeledBy Microsoft UI 자동화 속성에 대한 값을 가져오는 방법을 보여줍니다.

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

앞의 예제는 컨트롤 패턴과 연결되지 않은 속성에 적용됩니다. 제어 패턴 속성에 액세스하려면 클라이언트가 컨트롤 패턴 인터페이스를 가져오고 사용해야 합니다.

IRawElementProviderSimple 인터페이스에서 IAccessible 인터페이스 검색

클라이언트가 UI 요소에 대한 IRawElementProviderSimple 인터페이스를 가져오는 경우 클라이언트는 해당 인터페이스를 사용하여 요소에 해당하는 IAccessible 인터페이스를 가져올 수 있습니다. 이는 클라이언트가 요소에 대한 Microsoft Active Accessibility 속성에 액세스해야 하는 경우에 유용합니다.

클라이언트는 IRawElementProviderSimple 인터페이스를 속성 값(예: UIA_LabeledByPropertyId 사용하여 IRawElementProviderSimple::GetPropertyValue 호출) 또는 메서드에서 검색한 항목으로 가져올 수 있습니다(예: ISelectionProvider::GetSelection 을 호출하여 선택한 요소의 IRawElementProviderSimple 인터페이스 배열을 검색). IRawElementProviderSimple 인터페이스를 가져온 후 클라이언트는 이 인터페이스를 사용하여 다음 단계에 따라 해당 IAccessible을 가져올 수 있습니다.

다음 코드 조각은 이전에 가져온 IRawElementProviderSimple 인터페이스에서 IAccessible 인터페이스를 가져오는 방법을 보여 줍니다.

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