如何使用 消費者介面自動化 讓無視窗 ActiveX 控制項可供存取
描述如何使用 Microsoft 消費者介面自動化 API,確保您的無視窗 Microsoft ActiveX 控制項可供輔助技術 (AT) 用戶端應用程式存取。
您所需了解的事情
技術
必要條件
- C/C++
- Microsoft Win32 和元件物件模型 (COM) 程式設計
- 無視窗 ActiveX 控制項
- 消費者介面自動化提供者
指示
步驟 1:實作消費者介面自動化提供者介面。
若要讓應用程式可供存取,您必須實作無視窗 ActiveX 控制項的消費者介面自動化提供者介面,包括IRawElementProviderSimple、IRawElementProviderFragment、IRawElementProviderFragmentRoot和IRawElementProviderAdviseEvents。 您應該像針對視窗型控制項一樣實作這些介面,但下列步驟中所述除外。 如需實作 UIA 提供者介面的詳細資訊,請參閱消費者介面自動化提供者程式設計人員指南。
步驟 2:實作 IServiceProvider 介面。
當用戶端需要無視窗控制項的協助工具資訊時,控制項容器會呼叫控制項的 IServiceProvider::QueryService 方法,以擷取控制項的 IRawElementProviderSimple 介面指標。
下列範例示範如何實作 QueryService 方法。
STDMETHODIMP CMyAccessibleUIAControl::QueryService(REFGUID guidService,
REFIID riid, void **ppvObject)
{
if (ppvObject == NULL)
{
return E_INVALIDARG;
}
*ppvObject = NULL;
HRESULT hr = E_FAIL;
if (guidService == __uuidof(IRawElementProviderSimple))
{
hr = QueryInterface(riid, ppvObject);
}
return hr;
}
步驟 3:實作 IRawElementProviderFragment::Navigate 方法。
當無視窗控制項的 IRawElementProviderFragment::Navigate 方法被呼叫以巡覽至無視窗控制項根提供者的父系或同層級時, Navigate 方法應該委派給控制項容器的 IRawElementProviderWindowlessSite::GetAdjacentFragment 方法。
下列範例示範如何實作 Navigate 方法。
STDMETHODIMP CMyAccessibleUIAControl::Navigate(NavigateDirection direction,
IRawElementProviderFragment **ppRetVal)
{
if (ppRetVal == NULL)
{
return E_INVALIDARG;
}
*ppRetVal = NULL;
HRESULT hr = E_FAIL;
IRawElementProviderWindowlessSite *pWindowlessSite = NULL;
if (direction == NavigateDirection_Parent)
{
// Query the control container's windowless site
// for the parent.
if (SUCCEEDED(m_pClientSite->QueryInterface(
IID_PPV_ARGS(&pWindowlessSite))))
{
hr = pWindowlessSite->GetAdjacentFragment(direction, ppRetVal);
}
}
else if (direction == NavigateDirection_FirstChild)
{
// GetFragmentForChild is an application-defined function that
// retrieves the first or last child fragment.
hr = GetFragmentForChild(FIRST, ppRetVal);
}
else if (direction == NavigateDirection_LastChild)
{
hr = GetFragmentForChild(LAST, ppRetVal);
}
SafeRelease(&pWindowlessSite);
return S_OK;
}
步驟 4:實作 IRawElementProviderFragment::GetRuntimeId 方法。
當無視窗控制項收到其 IRawElementProviderFragment::GetRuntimeId 方法的呼叫時,控制項必須執行下列動作:
- 呼叫控制項網站的 IRawElementProviderWindowlessSite::GetRuntimeIdPrefix 方法,以擷取執行時間識別碼前置詞。
- 將整數附加至執行時間識別碼前置詞,為控制項建立唯一的執行時間識別碼。
- 將執行時間識別碼傳回給呼叫端。
下列範例示範如何實作 GetRuntimeId 方法。
STDMETHODIMP CMyAccessibleUIAControl::GetRuntimeId(SAFEARRAY **ppRetVal)
{
if (ppRetVal == NULL)
{
return E_INVALIDARG;
}
*ppRetVal = NULL;
HRESULT hr = E_FAIL;
IRawElementProviderWindowlessSite *pWindowlessSite = NULL;
if (SUCCEEDED(m_pClientSite->QueryInterface(IID_PPV_ARGS(&pWindowlessSite))))
{
// Create a safe array to hold runtime ID.
SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 1, 3);
if (psa == NULL)
{
hr = E_OUTOFMEMORY;
}
// Retrieve the runtime ID prefix from the control container. The prefix
// consists of UiaAppendRuntimeId followed by the windowless site ID.
if (SUCCEEDED(hr))
{
hr = pWindowlessSite->GetRuntimeIdPrefix(&psa);
}
if (SUCCEEDED(hr))
{
// Append this fragment's ID to the retrieved runtime ID prefix.
long i = 2;
hr = SafeArrayPutElement(psa, &i, (void*)&m_Id);
}
if (SUCCEEDED(hr))
{
*ppRetVal = psa;
}
}
SafeRelease(&pWindowlessSite);
return hr;
}
相關主題