Bagikan melalui


Menerapkan IAccessibleEx untuk Penyedia

Bagian ini menjelaskan cara menambahkan kemampuan penyedia Microsoft UI Automation ke server Microsoft Active Accessibility dengan menerapkan antarmuka IAccessibleEx.

Sebelum menerapkan IAccessibleEx, pertimbangkan persyaratan berikut:

  • Hierarki objek yang dapat diakses Aksesibilitas Aktif Microsoft garis besar harus bersih. IAccessibleEx tidak dapat memperbaiki masalah dengan hierarki objek yang dapat diakses yang ada. Setiap masalah dengan struktur model objek harus dikoreksi dalam implementasi Aksesibilitas Aktif Microsoft sebelum menerapkan IAccessibleEx.
  • Implementasi IAccessibleEx harus mematuhi spesifikasi Microsoft Active Accessibility dan spesifikasi Automation UI. Alat tersedia untuk memvalidasi kepatuhan di bawah kedua spesifikasi. Untuk informasi selengkapnya, lihat Menguji aksesibilitas dan Kerangka Kerja Automation Verify (UIA Verify) Test Automation.

Menerapkan IAccessibleEx memerlukan langkah-langkah utama berikut:

  • Terapkan IServiceProvider pada objek yang dapat diakses sehingga antarmuka IAccessibleEx dapat ditemukan pada objek ini atau terpisah.
  • Terapkan IAccessibleEx pada objek yang dapat diakses.
  • Buat objek yang dapat diakses untuk item anak Microsoft Active Accessibility apa pun, yang di Microsoft Active Accessibility diwakili oleh antarmuka IAccessible pada objek induk (misalnya, item daftar). Terapkan IAccessibleEx pada objek ini.
  • Terapkan IRawElementProviderSimple pada semua objek yang dapat diakses.
  • Terapkan antarmuka pola kontrol yang sesuai pada objek yang dapat diakses.

Menerapkan Antarmuka IServiceProvider

Karena implementasi IAccessibleEx untuk kontrol dapat berada di objek terpisah, aplikasi klien tidak dapat mengandalkan QueryInterface untuk mendapatkan antarmuka ini. Sebagai gantinya, klien diharapkan untuk memanggil IServiceProvider::QueryService. Dalam contoh implementasi metode ini berikut, diasumsikan bahwa IAccessibleEx tidak diimplementasikan pada objek terpisah; oleh karena itu metode hanya memanggil ke QueryInterface.

           
HRESULT CListboxAccessibleObject::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
{
    if (ppvObject == NULL)
    {
        return E_INVALIDARG;
    }
    *ppvObject = NULL;
    if (guidService == __uuidof(IAccessibleEx))
    {
        return QueryInterface(riid, ppvObject);
    }
    else 
    {
        return E_NOINTERFACE;
    }
};      

Menerapkan Antarmuka IAccessibleEx

Di Microsoft Active Accessibility, elemen UI selalu diidentifikasi oleh antarmuka IAccessible dan ID anak. Satu instans IAccessible dapat mewakili beberapa elemen UI.

Karena setiap instans IAccessibleEx hanya mewakili satu elemen UI, setiap pasangan IAccessible dan ID anak harus dipetakan ke satu instans IAccessibleEx. IAccessibleEx mencakup dua metode untuk menangani pemetaan ini:

Contoh berikut menunjukkan implementasi metode GetObjectForChild dan GetIAccessiblePair untuk item dalam tampilan daftar kustom. Metode ini memungkinkan Automasi UI untuk memetakan pasangan IAccessible dan ID anak ke instans IAccessibleEx yang sesuai.

           
HRESULT CListboxAccessibleObject::GetObjectForChild(
    long idChild, IAccessibleEx **ppRetVal)
{ 
    VARIANT vChild;
    vChild.vt = VT_I4;
    vChild.lVal = idChild;
    HRESULT hr = ValidateChildId(vChild);
    if (FAILED(hr))
    {
        return E_INVALIDARG;
    }
    // List item accessible objects are stored as an array of
    // pointers; for the purpose of this example it is assumed that 
    // the list contents will not change. Accessible objects are
    // created only when needed.
    if (itemProviders[idChild - 1] == NULL)
    {
        // Create an object that supports UI Automation and
        // IAccessibleEx for the item.
        itemProviders[idChild - 1] = 
          new CListItemAccessibleObject(idChild, 
          g_pListboxControl);
        if (itemProviders[idChild - 1] == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }
    IAccessibleEx* pAccEx = static_cast<IAccessibleEx*>
      (itemProviders[idChild - 1]);
    if (pAccEx != NULL)
    {
      pAccEx->AddRef();
    }
    *ppRetVal = pAccEx;
    return S_OK; 
}

HRESULT CListItemAccessibleObject::GetIAccessiblePair(
    IAccessible **ppAcc, long *pidChild)
{ 
    if (ppAcc == NULL || pidChild == NULL)
    {
        return E_INVALIDARG;   
    }

                CListboxAccessibleObject* pParent = 
        m_control->GetAccessibleObject();

    HRESULT hr = pParent->QueryInterface( 
        __uuidof(IAccessible), (void**)ppAcc);
    if (FAILED(hr))
    {
        *pidChild = 0;
        return E_NOINTERFACE;
    }
    *pidChild = m_childID; 
    return S_OK; 
}
}

Jika implementasi objek yang dapat diakses tidak menggunakan ID anak, metode masih dapat diimplementasikan seperti yang ditunjukkan dalam cuplikan kode berikut.

           

    // This sample implements IAccessibleEx on the same object; it could use a tear-off
    // or inner object instead.
    class MyAccessibleImpl: public IAccessible,
                        public IAccessibleEx,
                        public IRawElementProviderSimple
    {
    public:
    ...
   HRESULT STDMETHODCALLTYPE GetObjectForChild( long idChild, IAccessibleEx **ppRetVal )
    {
        // This implementation does not support child IDs.
        *ppRetVal = NULL;
        return S_OK;
    }

    HRESULT STDMETHODCALLTYPE GetIAccessiblePair( IAccessible ** ppAcc, long * pidChild )
    {
        // This implementation assumes that IAccessibleEx is implemented on same object as
        // IAccessible.
        *ppAcc = static_cast<IAccessible *>(this);
        (*ppAcc)->AddRef();
        *pidChild = CHILDID_SELF;
        return S_OK;
    }

Menerapkan Antarmuka IRawElementProviderSimple

Server menggunakan IRawElementProviderSimple untuk mengekspos informasi tentang properti dan pola kontrol Automation UI. IRawElementProviderSimple mencakup metode berikut:

Server IAccessibleEx mengekspos pola kontrol dengan menerapkan IRawElementProviderSimple::GetPatternProvider. Metode ini mengambil parameter bilangan bulat yang menentukan pola kontrol. Server mengembalikan NULL jika pola tidak didukung. Jika antarmuka pola kontrol didukung, server mengembalikan IUnknown dan klien kemudian memanggil QueryInterface untuk mendapatkan pola kontrol yang sesuai.

Server IAccessibleEx dapat mendukung properti Automation UI (seperti LabeledBy, dan IsRequiredForForm) dengan menerapkan IRawElementProviderSimple::GetPropertyValue dan menyediakan PROPERTYID bilangan bulat yang mengidentifikasi properti sebagai parameter. Teknik ini hanya berlaku untuk properti Automation UI yang tidak termasuk dalam antarmuka pola kontrol. Properti yang terkait dengan antarmuka pola kontrol diekspos melalui metode antarmuka pola kontrol. Misalnya, properti IsSelected dari pola kontrol SelectionItem akan diekspos dengan ISelectionItemProvider::get_IsSelected.