使用 MSAA 使无窗口 ActiveX 控件易于访问
介绍如何使用 Microsoft Active Accessibility API 确保辅助技术 (AT) 客户端应用程序可以访问无窗口 Microsoft ActiveX 控件。
需要了解的事项
技术
先决条件
- C/C++
- Microsoft Win32 和组件对象模型 (COM) 编程
- 无窗口 ActiveX 控件
- Microsoft Active Accessibility 服务器
Instructions
步骤 1:实现 IAccessible 接口。
若要使无窗口 ActiveX 控件易于访问,必须实现 Microsoft Active Accessibility IAccessible 接口,就像实现基于窗口的控件一样,但以下步骤中所述。 有关实现 IAccessible 的详细信息,请参阅 Active Accessibility Servers 开发人员指南。
步骤 2:实现 IServiceProvider 接口。
当客户端请求有关无窗口控件的辅助功能信息时,容器会调用控件的 IServiceProvider::QueryService 方法来检索 IAccessible 接口指针。
此示例演示如何实现 QueryService 方法。
STDMETHODIMP CMyAccessibleMSAAControl::QueryService(REFGUID guidService,
REFIID riid, void **ppvObject)
{
if (ppvObject == NULL)
{
return E_INVALIDARG;
}
*ppvObject = NULL;
HRESULT hr = E_FAIL;
if (guidService == __uuidof(IAccessible))
{
hr = QueryInterface(riid, ppvObject);
}
return hr;
}
步骤 3:将 IAccessible::get_accParent 方法调用委托给控件网站的 IAccessibleWindowlessSite::GetParentAccessible 方法。
当客户端请求无窗口控件的父对象时,容器会调用控件的 IAccessible::get_accParent 方法。 get_accParent实现应委托给容器的 IAccessibleWindowlessSite::GetParentAccessible 方法。
此示例演示如何实现 get_accParent 方法。
HRESULT CMyAccessibleMSAAControl::get_accParent(IDispatch **ppdispParent)
{
if (ppdispParent == NULL)
{
return E_INVALIDARG;
}
HRESULT hr = S_FALSE;
*ppdispParent = NULL;
IAccessibleWindowlessSite *pWindowlessSite = NULL;
if (SUCCEEDED(m_pClientSite->QueryInterface(IID_PPV_ARGS(&pWindowlessSite))))
{
IAccessible *pParentAcc = NULL;
if (SUCCEEDED(pWindowlessSite->GetParentAccessible(&pParentAcc)))
{
hr = pParentAcc->QueryInterface(IID_PPV_ARGS(ppdispParent));
}
}
SafeRelease(&pWindowlessSite);
return hr;
}
步骤 4:获取要分配给无窗口控件中的事件源的对象 ID 的范围。
与基于窗口的控件一样,无窗口 ActiveX 控件调用 NotifyWinEvent 函数来通知客户端重要事件。 函数参数包括引发事件的项的对象 ID。 无窗口控件必须使用通过调用控件站点的 IAccessibleWindowlessSite::AcquireObjectIdRange 方法获取的范围中的值来分配对象 ID。
此示例演示如何从控制容器获取一系列对象 ID 值。
IAccessibleWindowlessSite *pWindowlessSite = NULL;
if (SUCCEEDED(m_pClientSite->QueryInterface(
IID_PPV_ARGS(&pWindowlessSite))))
{
if (FAILED(pWindowlessSite->AcquireObjectIdRange(100, this,
&m_idObjectBase)))
{
m_idObjectBase = -1;
}
}
SafeRelease(&pWindowlessSite);
步骤 5:实现 IAccessibleHandler 接口。
当无窗口控件调用 NotifyWinEvent 函数时,控件指定引发事件的 UI 项的对象 ID,并将控件容器指定为代表控件响应 WM_GETOBJECT 消息的窗口。
如果客户端应用程序响应事件,则控件容器会收到 一条WM_GETOBJECT 消息,其中包含引发该事件的 UI 项的对象 ID。 控件容器通过查找“拥有”对象 ID 的无窗口控件,然后调用该控件的 IAccessibleHandler::AccessibleObjectFromID 方法进行响应。 AccessibleObjectFromID 方法返回 UI 项的 IAccessible 接口指针,控件容器将指针转发到客户端应用程序。
相关主题