获取Firefox / Thunderbird窗口的IAccessible2接口- QueryService总是返回E_



我正在尝试使用IAccessible2 API: http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2访问(仅限Windows) Firefox/Thunderbird中的信息然而我几乎在第一步就失败了。我可以获得两个应用程序的IAccessible接口,然后是IServiceProvider接口。但是当我调用QueryService来获取IAccessible2接口时,如下所述:http://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_generalinfo.html#_dicoveringInterfaces它总是返回E_INVALIDARG。

AccProbe成功返回两个应用程序的IA2信息。QueryService的MS文档没有将E_INVALIDARG列为可能的返回值。然而,浏览mozilla源代码会发现,如果第一个参数(服务ID)是意外的,则返回this,否则调用QueryInterface(对于错误的接口ID将返回E_NOINTERFACE)。所以…这意味着QueryService的第一个参数是错误的;但是我已经尝试了我认为mozilla期望的几乎所有值,没有任何差异。

我从c#开始,然后在c++中再次尝试,以防我在InterOp中丢失一些东西。两种语言的结果相同。下面是我当前的c++测试代码:

    HWND hw = GetForegroundWindow();
    IAccessible *pIA;
    HRESULT hr = AccessibleObjectFromWindow(hw, OBJID_WINDOW, IID_IAccessible, (void**)&pIA);
    if (!SUCCEEDED(hr))
        return -1;
    // SNIP - calls pIA->get_accName to check correct window is being accessed.  This works OK.
    const IID IID_IAccessible2 = {0xE89F726E, 0xC4F4, 0x4c19, 0xbb, 0x19, 0xb6, 0x47, 0xd7, 0xfa, 0x84, 0x78};
    ::IServiceProvider *pService = NULL; 
    hr = pIA->QueryInterface(IID_IServiceProvider, (void **)&pService); 
    if(SUCCEEDED(hr))
    {
        IAccessible2 *pIA2 = NULL; 
        hr = pService->QueryService(IID_IAccessible2, IID_IAccessible2, (void**)&pIA2); 
        if (SUCCEEDED(hr) && pIA2)
        { 
          // Always fails with E_INVALIDARG
            pIA2->Release();
        } 
        pService->Release();
    } 

这都是在Win7上- 32位和64位都使用。Firefox 3.6.24和Thunderbird 8.0。Visual Studio 2005

我做错了什么吗?

HRESULT hr = AccessibleObjectFromWindow(hw, OBJID_WINDOW, IID_IAccessible, (void**)&pIA);
if (!SUCCEEDED(hr))
    return -1;

我认为问题在这里-用OBJID_CLIENT替换OBJID_WINDOW,它似乎起作用了。(我没有注册typelib,但我可以QS IID_IAccessible和IUnknown接口,它似乎起作用了。此外,请确保CoInitialize() Also。)

IAccessible有一个有趣的层次结构:每个HWND都有一个"窗口"部分和一个"客户端"部分。这部分是由于Win32的内部工作方式;Win32 HWND可以拥有标题栏、菜单、滚动条等项目,它们都共享相同的HWND -以及实际控件内容所在的内容区域(即客户端区域)。为了让这些项目有自己的表示,MSAA的设计者选择了一个两层结构,其中OBJID_WINDOW代表整个窗口,它的子结构代表滚动条、菜单栏、标题栏等——如果它们存在的话。

实现可访问性的窗口部分,然而,通常是客户端部分,所以你通常需要请求OBJID_CLIENT来获得'真正的' IAccessible。

相关内容

  • 没有找到相关文章

最新更新