Bagikan melalui


Menambahkan Fungsionalitas Automasi UI ke Server Aksesibilitas Aktif

Kontrol yang tidak memiliki penyedia Microsoft UI Automation tetapi yang mengimplementasikan IAccessible dapat dengan mudah ditingkatkan untuk menyediakan beberapa fungsionalitas Automation UI, dengan mengimplementasikan antarmuka IAccessibleEx. Antarmuka ini memungkinkan kontrol untuk mengekspos properti Automation UI dan pola kontrol, tanpa perlu implementasi penuh antarmuka penyedia Automation UI seperti IRawElementProviderFragment. Untuk mengimplementasikan IAccessibleEx, hierarki objek Aksesibilitas Aktif Microsoft garis besar tidak boleh berisi kesalahan atau inkonsistensi (seperti objek anak yang objek induknya tidak mencantumkannya sebagai turunan), dan tidak boleh bertentangan dengan spesifikasi Automasi UI. Jika hierarki objek Aksesibilitas Aktif Microsoft memenuhi persyaratan ini, ini adalah kandidat yang baik untuk menambahkan fungsionalitas dengan menggunakan IAccessibleEx; jika tidak, Anda harus menerapkan Otomatisasi UI saja atau bersama implementasi Aksesibilitas Aktif Microsoft.

Ambil kasus kontrol kustom yang memiliki nilai rentang. Server Aksesibilitas Aktif Microsoft untuk kontrol menentukan perannya, dan dapat mengembalikan nilainya saat ini, tetapi tidak memiliki sarana untuk mengembalikan nilai minimum dan maksimum kontrol, karena properti ini tidak ditentukan dalam Aksesibilitas Aktif Microsoft. Klien Automation UI dapat mengambil peran kontrol, nilai saat ini, dan properti Microsoft Active Accessibility lainnya, karena inti Automation UI dapat memperolehnya melalui IAccessible. Namun, tanpa akses ke antarmuka IRangeValueProvider pada objek, Automasi UI juga tidak dapat mengambil nilai maksimum dan minimum.

Pengembang kontrol dapat menyediakan penyedia Automation UI lengkap untuk kontrol, tetapi ini berarti menduplikasi sebagian besar fungsionalitas yang ada dari implementasi IAccessible : misalnya, navigasi dan properti umum. Sebagai gantinya, pengembang dapat terus mengandalkan IAccessible untuk menyediakan fungsionalitas ini, sambil menambahkan dukungan untuk properti khusus kontrol melalui IRangeValueProvider.

Memperbarui kontrol kustom memerlukan langkah-langkah utama ini:

Topik ini berisi bagian berikut.

Mengekspos IAccessibleEx

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)
    {
        return E_INVALIDARG;
    }
    *ppvObject = NULL;
    if (guidService == __uuidof(IAccessibleEx))
    {
        return QueryInterface(riid, ppvObject);
    }
    else 
    {
        return E_INVALIDARG;
    }
};

Menerapkan IAccessibleEx

Metode IAccessibleEx yang paling menarik adalah GetObjectForChild. Metode ini memberi server Aksesibilitas Aktif Microsoft kesempatan untuk membuat objek yang dapat diakses (yang mengekspos, minimal, IAccessibleEx) untuk item anak. Di Microsoft Active Accessibility, item anak biasanya tidak direpresentasikan sebagai objek yang dapat diakses tetapi sebagai turunan dari objek yang dapat diakses. Namun, karena Automasi UI mengharuskan setiap elemen diwakili oleh objek yang dapat diakses terpisah, GetObjectForChild harus membuat objek terpisah untuk setiap anak sesuai permintaan.

Contoh implementasi berikut mengembalikan objek yang dapat diakses untuk item dalam tampilan daftar kustom.

HRESULT CListboxAccessibleObject::GetObjectForChild(long idChild, IAccessibleEx **pRetVal)
{ 
    *pRetVal = NULL;
    VARIANT vChild;
    vChild.vt = VT_I4;
    vChild.lVal = idChild;

    // ValidateChildId is an application-defined function that checks whether
    // the child ID is valid. This is similar to code that validates the varChild
    // parameter in IAccessible methods.
    //
    // Additionally, if this idChild corresponds to a child that has its own
    // IAccessible, we should also return E_INVALIDARG here. (The caller
    // should instead be using the IAccessibleEx from that child's own
    // IAccessible in that case.)
    if (idChild == CHILDID_SELF || FAILED(ValidateChildId(vChild)))
    {
        return E_INVALIDARG;
    }

    // Return a suitable provider for this specific child.
    // This implementation returns a new instance each time; an implementation
    // can cache these if desired.

    // _pListboxControl is a member variable pointer to the owning control.
    IAccessibleEx* pAccEx  = new CListItemAccessibleObject(idChild, _pListboxControl);
    if (pAccEx == NULL)
    {
        return E_OUTOFMEMORY;
    }
    *pRetVal = pAccEx;
    return S_OK; 
}

Untuk implementasi sampel lengkap, lihat Membuat Kontrol Kustom Dapat Diakses, Bagian 5: Menggunakan IAccessibleEx untuk Menambahkan Dukungan Automasi UI ke Kontrol Kustom.

Panduan Programmer Penyedia Automation UI