Implementieren von IAccessibleEx für Anbieter
In diesem Abschnitt wird erläutert, wie Sie einem Microsoft Active Accessibility-Server Funktionen von Microsoft Benutzeroberflächenautomatisierung-Anbietern hinzufügen, indem Sie die IAccessibleEx-Schnittstelle implementieren.
Berücksichtigen Sie vor der Implementierung von IAccessibleExdie folgenden Anforderungen:
- Die Baseline Microsoft Active Accessibility barrierefreien Objekthierarchie muss bereinigt sein. IAccessibleEx kann Probleme mit vorhandenen barrierefreien Objekthierarchien nicht beheben. Alle Probleme mit der Objektmodellstruktur müssen in der Microsoft Active Accessibility Implementierung behoben werden, bevor IAccessibleEx implementiert wird.
- Die IAccessibleEx-Implementierung muss sowohl der Microsoft Active Accessibility- als auch der Benutzeroberflächenautomatisierung-Spezifikation entsprechen. Tools sind verfügbar, um die Konformität in beiden Spezifikationen zu überprüfen. Weitere Informationen finden Sie unter Testtools und Benutzeroberflächenautomatisierung Verify (UIA Verify) Test Automation Framework.
Die Implementierung von IAccessibleEx erfordert die folgenden Hauptschritte:
- Implementieren Sie IServiceProvider für das barrierefreie Objekt, sodass die IAccessibleEx-Schnittstelle in diesem oder einem separaten Objekt gefunden werden kann.
- Implementieren Sie IAccessibleEx für das barrierefreie Objekt.
- Erstellen Sie barrierefreie Objekte für alle Microsoft Active Accessibility untergeordneten Elemente, die in Microsoft Active Accessibility durch die IAccessible-Schnittstelle für das übergeordnete Objekt (z. B. Listenelemente) dargestellt werden. Implementieren Sie IAccessibleEx für diese Objekte.
- Implementieren Sie IRawElementProviderSimple für alle barrierefreien Objekte.
- Implementieren Sie die entsprechenden Steuerelementmusterschnittstellen für die barrierefreien Objekte.
Implementieren der IServiceProvider-Schnittstelle
Da sich die Implementierung von IAccessibleEx für ein Steuerelement in einem separaten -Objekt befinden kann, können Clientanwendungen sich nicht auf QueryInterface verlassen, um diese Schnittstelle abzurufen. Stattdessen wird von Clients erwartet, dass sie IServiceProvider::QueryService aufrufen. In der folgenden Beispielimplementierungen dieser Methode wird davon ausgegangen, dass IAccessibleEx nicht für ein separates -Objekt implementiert ist. daher ruft die -Methode einfach durch auf QueryInterface auf.
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;
}
};
Implementieren der IAccessibleEx-Schnittstelle
In Microsoft Active Accessibility wird ein Benutzeroberflächenelement immer durch eine IAccessible-Schnittstelle und eine untergeordnete ID identifiziert. Eine einzelne Instanz von IAccessible kann mehrere Benutzeroberflächenelemente darstellen.
Da jede IAccessibleEx-Instanz nur ein einzelnes Benutzeroberflächenelement darstellt, muss jedes IAccessible- und untergeordnete ID-Paar einer einzelnen IAccessibleEx-Instanz zugeordnet werden. IAccessibleEx umfasst zwei Methoden zum Behandeln dieser Zuordnung:
- GetObjectForChild: Ruft die IAccessibleEx-Schnittstelle für das angegebene untergeordnete Element ab. Diese Methode gibt NULL zurück, wenn die IAccessibleEx-Implementierung die angegebene untergeordnete ID nicht erkennt, keinen IAccessibleEx für das angegebene untergeordnete Element besitzt oder ein untergeordnetes Element darstellt.
- GetIAccessiblePair: Ruft die IAccessible-Schnittstelle und die untergeordnete ID für das IAccessibleEx-Element ab. Für IAccessible-Implementierungen, die keine untergeordnete ID verwenden, ruft diese Methode das entsprechende IAccessible-Objekt und CHILDID _ SELF ab.
Das folgende Beispiel zeigt die Implementierung der Methoden GetObjectForChild und GetIAccessiblePair für ein Element in einer benutzerdefinierten Listenansicht. Die Methoden ermöglichen Benutzeroberflächenautomatisierung, das IAccessible- und das untergeordnete ID-Paar einer entsprechenden IAccessibleEx-Instanz zuzuordnen.
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;
}
}
Wenn eine barrierefreie Objektimplementierungen keine untergeordnete ID verwenden, können die Methoden weiterhin implementiert werden, wie im folgenden Codeausschnitt gezeigt.
// 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;
}
Implementieren der IRawElementProviderSimple-Schnittstelle
Server verwenden IRawElementProviderSimple, um Informationen zu Benutzeroberflächenautomatisierung Eigenschaften und Steuerelementmustern verfügbar zu machen. IRawElementProviderSimple umfasst die folgenden Methoden:
- GetPatternProvider: Diese Methode wird verwendet, um Steuerelementmusterschnittstellen verfügbar zu machen. Sie gibt ein Objekt zurück, das das angegebene Steuerelementmuster unterstützt, oder NULL, wenn das Steuerelementmuster nicht unterstützt wird.
- GetPropertyValue: Diese Methode wird verwendet, um Benutzeroberflächenautomatisierung Eigenschaftswerte verfügbar zu machen.
- HostRawElementProvider: Diese Methode wird nicht mit IAccessibleEx-Implementierungen verwendet.
- ProviderOptions: Diese Methode wird nicht mit IAccessibleEx-Implementierungen verwendet.
Ein IAccessibleEx-Server macht Steuerelementmuster verfügbar, indem IRawElementProviderSimple::GetPatternProviderimplementiert wird. Diese Methode akzeptiert einen ganzzahligen Parameter, der das Steuerelementmuster angibt. Der Server gibt NULL zurück, wenn das Muster nicht unterstützt wird. Wenn die Steuerelementmusterschnittstelle unterstützt wird, geben Server eine IUnknown-Schnittstelle zurück, und der Client ruft dann QueryInterface auf, um das entsprechende Steuerelementmuster abzurufen.
Ein IAccessibleEx-Server kann Benutzeroberflächenautomatisierung Eigenschaften (z. B. LabeledBy und IsRequiredForForm) unterstützen, indem IRawElementProviderSimple::GetPropertyValue implementiert und eine ganzzahlige PROPERTYID angegeben wird, die die Eigenschaft als Parameter identifiziert. Diese Technik gilt nur für Benutzeroberflächenautomatisierung Eigenschaften, die nicht in einer Steuerelementmusterschnittstelle enthalten sind. Eigenschaften, die einer Steuerelementmusterschnittstelle zugeordnet sind, werden über die Methode der Steuerelementmusterschnittstelle verfügbar gemacht. Beispielsweise würde die IsSelected-Eigenschaft aus dem SelectionItem-Steuerelementmuster mit ISelectionItemProvider::get _ IsSelectedverfügbar gemacht werden.