2

IAccessible2 APIを使用して(Windowsのみ)Firefox / Thunderbirdの情報にアクセスしようとしています:http ://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2 しかし、ほとんど最初のステップで失敗しています。どちらのアプリケーションでも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)が予期しない場合はこれが返され、それ以外の場合はQueryInterface(不正なインターフェイスIDの場合はE_NOINTERFACEが返されます)が呼び出されます。つまり...これは、QueryServiceの最初のパラメーターが間違っていることを意味します。しかし、私はMozillaが期待するほとんどすべての値を、違いなく試しました。

私はc#で始めて、InterOpで何かを失った場合に備えて、c++で再試行しました。両方の言語で同じ結果。これが私の現在の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ビットの両方が使用されます。Firefox3.6.24およびThunderbird8.0。Visual Studio 2005

私は何か間違ったことをしていますか?

4

1 に答える 1

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

問題はここにあると思います-OBJID_WINDOWをOBJID_CLIENTに置き換えれば、機能しているようです。(typelibを登録していませんが、IID_IAccessibleおよびIUnknownインターフェイスのQSを実行でき、機能しているようです。また、CoInitialize()も必ず実行してください。)

IAccessibleには興味深い階層があります。すべてのHWNDには、「ウィンドウ」部分と「クライアント」部分の両方があります。これは、Win32が内部でどのように機能するかによって部分的に発生します。Win32 HWNDには、タイトルバー、メニュー、スクロールバーなど、すべて同じHWNDを共有するアイテムを含めることができます。コンテンツ領域、つまり実際のコントロールコンテンツが存在するクライアント領域も同様です。これらのアイテムに独自の表現を持たせるために、MSAAの設計者は2レベルの構造を選択しました。ここで、OBJID_WINDOWはウィンドウ全体を表し、子があり、スクロールバー、メニューバー、タイトルバーなどを表します。現在。

ただし、アクセス可能性を実装するウィンドウの部分は通常、クライアント部分であるため、通常、「実際の」IAccessibleを取得するにはOBJID_CLIENTを要求する必要があります。

于 2011-12-13T11:06:43.997 に答える