クライアントからの IAccessibleEx の使用
このトピックでは、クライアントがサーバーの IAccessibleEx 実装にアクセスし、それを使用して UI 要素のプロパティとコントロール パターンUI オートメーション取得する方法について説明します。
このセクションの手順と例では、既に処理中の IAccessible クライアントと、既存の Microsoft Active Accessibility サーバーを想定しています。 また、AccesseObjectFromEvent、AccessibleObjectFromPoint、AccessibleObjectFromWindow などのアクセシビリティ フレームワーク関数のいずれかを使用して、クライアントが既に IAccessible オブジェクトを取得していることを前提としています。
IAccessible インターフェイスから IAccessibleEx インターフェイスを取得する
アクセス可能なオブジェクトの IAccessible インターフェイスを持つクライアントは、次の手順に従って、それを使用して対応する IAccessibleEx インターフェイスを取得できます。
- IID が __uuidof(IServiceProvider) の元の IAccessible オブジェクトで QueryInterface を呼び出します。
- IServiceProvider::QueryService を呼び出して、IAccessibleEx を取得します。
子 ID の処理
クライアントは、CHILDID_SELF以外の子 ID を持つサーバー用に準備する必要があります。 IAccessible から IAccessibleEx インターフェイスを取得した後、子 ID が (親オブジェクトを示す) CHILDID_SELFされていない場合、クライアントは IAccessibleEx::GetObjectForChild を呼び出す必要があります。
次の例は、特定の IAccessible オブジェクトと子 ID の IAccessibleEx を取得する方法を示しています。
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;
}
}
IRawElementProviderSimple インターフェイスの取得
クライアントに IAccessibleEx インターフェイスがある場合、次の例に示すように、QueryInterface を使用して IRawElementProviderSimple インターフェイスにアクセスできます。
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;
}
コントロール パターンの取得
クライアントが IRawElementProviderSimple インターフェイスにアクセスできる場合は、プロバイダーによって実装されたコントロール パターン インターフェイスを取得し、それらのインターフェイスでメソッドを呼び出すことができます。 次の例は、その方法を示したものです。
// 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;
}
プロパティ値の取得
クライアントが IRawElementProviderSimple にアクセスできる場合は、プロパティ値を取得できます。 次の例は、AutomationId プロパティと LabeledBy Microsoft UI オートメーション プロパティの値を取得する方法を示しています。
#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);
}
前の例は、コントロール パターンに関連付けられていないプロパティに適用されます。 制御パターンのプロパティにアクセスするには、クライアントがコントロール パターン インターフェイスを取得して使用する必要があります。
IRawElementProviderSimple インターフェイスから IAccessible インターフェイスを取得する
クライアントが UI 要素の IRawElementProviderSimple インターフェイスを取得した場合、クライアントはそのインターフェイスを使用して、 要素の対応する IAccessible インターフェイスを取得できます。 これは、クライアントが 要素の Microsoft Active Accessibility プロパティにアクセスする必要がある場合に便利です。
クライアントは 、IRawElementProviderSimple インターフェイスをプロパティ値として取得できます (たとえば、UIA_LabeledByPropertyIdを使用して IRawElementProviderSimple::GetPropertyValue を呼び出す)、またはメソッドによって取得されたアイテムとして取得できます (たとえば、 ISelectionProvider::GetSelection を呼び出して、選択した要素の IRawElementProviderSimple インターフェイスの配列を取得します)。 IRawElementProviderSimple インターフェイスを取得した後、クライアントはそれを使用して、次の手順に従って対応する IAccessible を取得できます。
- QueryInterface を使用して IAccessibleEx インターフェイスを取得しようとします。
- QueryInterface が失敗した場合は、プロパティが最初に取得された IAccessibleEx インスタンスで IAccessibleEx::ConvertReturnedElement を呼び出します。
- 新しい IAccessibleEx インスタンスで GetIAccessiblePair メソッドを呼び出して、IAccessible interfae と子 ID を取得します。
次のコード スニペットは、以前に取得した IRawElementProviderSimple インターフェイスから IAccessible インターフェイスを取得する方法を示しています。
// 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.
...
}
}