Freigeben über


Hinzufügen von Benutzeroberflächenautomatisierungsfunktionen zu aktiven Barrierefreiheitsservern

Steuerelemente, die nicht über einen Microsoft UI Automation-Anbieter verfügen, aber IAccessible implementieren, können problemlos aktualisiert werden, um einige UI Automation-Funktionen bereitzustellen, indem die IAccessibleEx-Schnittstelle implementiert wird. Diese Schnittstelle ermöglicht es dem Steuerelement, UI Automation-Eigenschaften und Steuerelementmuster verfügbar zu machen, ohne dass eine vollständige Implementierung von UI Automation-Anbieterschnittstellen wie IRawElementProviderFragment erforderlich ist. Zur Implementierung von IAccessibleEx darf die grundlegende Microsoft Active Accessibility-Objekthierarchie keine Fehler oder Inkonsistenzen enthalten (z. B. ein untergeordnetes Objekt, dessen übergeordnetes Objekt es nicht als untergeordnetes Objekt auflistet) und nicht mit UI Automation-Spezifikationen in Konflikt stehen. Wenn die Microsoft Active Accessibility-Objekthierarchie diese Anforderungen erfüllt, ist sie ein guter Kandidat für das Hinzufügen von Funktionen mithilfe von IAccessibleEx. Andernfalls müssen Sie UI Automation allein oder zusammen mit der Microsoft Active Accessibility-Implementierung implementieren.

Betrachten wir den Fall eines benutzerdefinierten Steuerelements mit einem Bereichswert. Der Microsoft Active Accessibility-Server für das Steuerelement definiert seine Rolle und kann seinen aktuellen Wert zurückgeben, hat jedoch nicht die Möglichkeit, die Mindest- und Höchstwerte des Steuerelements zurückzugeben, da diese Eigenschaften in Microsoft Active Accessibility nicht definiert sind. Ein UI Automation-Client kann die Rolle, den aktuellen Wert und andere Microsoft Active Accessibility-Eigenschaften abrufen, da der Kern von UI Automation diese über IAccessible abrufen kann. Ohne Zugriff auf eine IRangeValueProvider-Schnittstelle für das Objekt kann UI Automation jedoch ebenfalls die Maximal- und Mindestwerte nicht abrufen.

Der Steuerelemententwickler könnte einen vollständigen UI Automation-Anbieter für das Steuerelement bereitstellen. Dies würde jedoch bedeuten, einen Großteil der vorhandenen Funktionen der IAccessible-Implementierung zu duplizieren: z. B. Navigation und allgemeine Eigenschaften. Stattdessen kann der Entwickler weiterhin auf IAccessible zurückgreifen, um diese Funktionalität bereitstellen zu können, während die Unterstützung für steuerelementspezifische Eigenschaften über IRangeValueProvider hinzugefügt wird.

Zum Aktualisieren des benutzerdefinierten Steuerelements sind die folgenden Hauptschritte erforderlich:

  • Implementieren von IServiceProvider für das barrierefreie Objekt, sodass die IAccessibleEx-Schnittstelle in diesem oder einem separaten Objekt gefunden werden kann.
  • Implementieren von IAccessibleEx für das barrierefreie Objekt.
  • Erstellen Sie unterschiedliche barrierefreie Objekte für alle untergeordneten Microsoft Active Accessibility-Elemente, die in Microsoft Active Accessibility möglicherweise durch die IAccessible-Schnittstelle für das übergeordnete Objekt repräsentiert wurden (z. B. Listenelemente). Implementieren von IAccessibleEx für diese Objekte.
  • Implementieren von IRawElementProviderSimple für alle barrierefreien Objekte.
  • Implementieren der entsprechenden Steuerelementmusterschnittstellen für die barrierefreien Objekte.

Dieses Thema enthält folgende Abschnitte:

Verfügbarmachen von IAccessibleEx

Da sich die Implementierung von IAccessibleEx für ein Steuerelement möglicherweise in einem separaten Objekt befindet, können Clientanwendungen sich nicht auf QueryInterface verlassen, um diese Schnittstelle abzurufen. Stattdessen wird erwartet, dass Clients IServiceProvider::QueryService aufrufen. In der folgenden Beispielimplementierung dieser Methode wird davon ausgegangen, dass IAccessibleEx nicht für ein separates Objekt implementiert ist. Daher wird die Methode einfach über QueryInterface aufgerufen.

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

Implementieren von IAccessibleEx

Die Methode von IAccessibleEx, die hier am meisten interessiert, ist GetObjectForChild. Diese Methode bietet dem Microsoft Active Accessibility-Server die Möglichkeit, ein barrierefreies Objekt (ein Objekt, das mindestens IAccessibleEx verfügbar macht) für ein untergeordnetes Element zu erstellen. In Microsoft Active Accessibility werden untergeordnete Elemente in der Regel nicht als barrierefreie Objekte repräsentiert, sondern als untergeordnete Elemente eines barrierefreien Objekts. Da UI Automation jedoch erfordert, dass jedes Element durch ein separates barrierefreies Objekt repräsentiert wird, muss GetObjectForChild für jedes untergeordnete Element bei Bedarf ein separates Objekt erstellen.

Die folgende Beispielimplementierung gibt ein barrierefreies Objekt für ein Element in einer benutzerdefinierten Listenansicht zurück.

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

Eine vollständige Beispielimplementierung finden Sie unter Barrierefreiheit für benutzerdefinierte Steuerelemente, Teil 5: Verwendung von IAccessibleEx zum Hinzufügen von UI Automation-Unterstützung zu einem benutzerdefinierten Steuerelement.

Programmierhandbuch für UI Automation-Anbieter