Bagikan melalui


Menggunakan IAccessibleEx dari Klien

Topik ini menjelaskan bagaimana klien mengakses implementasi IAccessibleEx server dan menggunakannya untuk mendapatkan properti Automation UI dan pola kontrol untuk elemen UI.

Prosedur dan contoh di bagian ini mengasumsikan klien IAccessible yang sudah dalam proses, dan server Aksesibilitas Aktif Microsoft yang ada. Mereka juga berasumsi bahwa klien telah mendapatkan objek IAccessible dengan menggunakan salah satu fungsi kerangka kerja aksesibilitas seperti AccessibleObjectFromEvent, AccessibleObjectFromPoint, atau AccessibleObjectFromWindow.

Mendapatkan Antarmuka IAccessibleEx dari Antarmuka IAccessible

Klien yang memiliki antarmuka IAccessible untuk objek yang dapat diakses dapat menggunakannya untuk mendapatkan antarmuka IAccessibleEx yang sesuai dengan mengikuti langkah-langkah berikut:

Menangani ID Anak

Klien harus siap untuk server dengan ID anak selain CHILDID_SELF. Setelah mendapatkan antarmuka IAccessibleEx dari IAccessible, klien harus memanggil IAccessibleEx::GetObjectForChild jika ID anak tidak CHILDID_SELF (menunjukkan objek induk).

Contoh berikut menunjukkan cara mendapatkan IAccessibleEx untuk objek IAccessible dan ID anak tertentu.

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

Mendapatkan Antarmuka IRawElementProviderSimple

Jika klien memiliki antarmuka IAccessibleEx , klien dapat menggunakan QueryInterface untuk masuk ke antarmuka IRawElementProviderSimple , seperti yang ditunjukkan contoh berikut.

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

Mengambil Pola Kontrol

Jika klien memiliki akses ke antarmuka IRawElementProviderSimple , klien dapat mengambil antarmuka pola kontrol yang telah diterapkan oleh penyedia, dan kemudian dapat memanggil metode pada antarmuka tersebut. Contoh berikut menunjukkan cara melakukannya.

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

Mengambil Nilai Properti

Jika klien memiliki akses ke IRawElementProviderSimple, klien dapat mengambil nilai properti. Contoh berikut menunjukkan cara mendapatkan nilai untuk properti AutomationId dan LabeledBy Microsoft UI Automation.

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

Contoh sebelumnya berlaku untuk properti yang tidak terkait dengan pola kontrol. Untuk mengakses properti pola kontrol, klien harus mendapatkan dan menggunakan antarmuka pola kontrol.

Mengambil Antarmuka IAccessible dari Antarmuka IRawElementProviderSimple

Jika klien mendapatkan antarmuka IRawElementProviderSimple untuk elemen UI, klien dapat menggunakan antarmuka tersebut untuk mendapatkan antarmuka IAccessible yang sesuai untuk elemen tersebut. Ini berguna jika klien perlu mengakses properti Aksesibilitas Aktif Microsoft untuk elemen tersebut.

Klien dapat memperoleh antarmuka IRawElementProviderSimple sebagai nilai properti (misalnya, dengan memanggil IRawElementProviderSimple::GetPropertyValue dengan UIA_LabeledByPropertyId), atau sebagai item yang diambil oleh metode (misalnya, dengan memanggil ISelectionProvider::GetSelection untuk mengambil array antarmuka IRawElementProviderSimple dari elemen yang dipilih). Setelah mendapatkan antarmuka IRawElementProviderSimple , klien dapat menggunakannya untuk mendapatkan IAccessible yang sesuai dengan mengikuti langkah-langkah berikut:

Cuplikan kode berikut menunjukkan cara mendapatkan antarmuka IAccessible dari antarmuka IRawElementProviderSimple yang diperoleh sebelumnya.

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