2011-12-11 3 views
1

를 반환합니다. 응용 프로그램과 IServiceProvider 인터페이스에 대한 IAccessible 인터페이스를 얻을 수 있습니다. 그러나 여기에 설명 된대로 IAccessible2 인터페이스를 얻기 위해 QueryService를 호출하면 http://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_generalinfo.html#_dicoveringInterfaces은 항상 E_INVALIDARG를 반환합니다.얻기 IAccessible2 인터페이스하여 QueryService는 항상 내가 IAccessible2 API를 사용 (Windows 만 해당) 파이어 폭스/썬더 버드에있는 정보에 액세스 시도하고 E_INVALIDARG

AccProbe가 두 응용 프로그램 모두에 대해 IA2 정보를 성공적으로 반환합니다. QueryService에 대한 MS 설명서에서 E_INVALIDARG을 가능한 반환 값으로 나열하지 않습니다. 그러나 모질라 소스를 검색하면 첫 번째 매개 변수 (서비스 ID)가 예기치 않은 경우이를 반환하고 그렇지 않으면 QueryInterface (잘못된 인터페이스 ID에 대해 E_NOINTERFACE를 반환)를 호출하는 것으로 나타납니다. 그래서 ... 이것은 QueryService의 첫 번째 매개 변수가 잘못되었음을 의미합니다. 그러나 나는 모질라가 아무런 차이도없이 기대하는 모든 가치를 거의 시도해 보았습니다.

나는 InterOp에서 뭔가를 잃어 버렸을 경우를 대비하여 C#에서 시작한 다음 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 비트)에서 사용됩니다. 파이어 폭스 3.6.24 및 썬더 버드 8.0. Visual Studio 2005

잘못된 것이 있습니까?

답변

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

여기 문제가 있다고 생각합니다. OBJID_WINDOW를 OBJID_CLIENT로 바꾸면 작동하는 것 같습니다. (나는 typelib을 등록하지 않았지만 IID_IAccessible 및 IUnknown 인터페이스에 대해 QS를 수행 할 수 있으며 작동하는 것으로 보입니다.)

IAccessible은 흥미로운 계층 구조를 갖습니다. 모든 HWND '창'부분과 '클라이언트'부분이 둘 다 있습니다. 이는 부분적으로 Win32가 내부적으로 어떻게 작동하는지에 기인합니다. Win32 HWND는 titlebar, menu, scrollbars 등과 같은 항목을 가질 수 있습니다. 모든 HWND는 실제로 콘트롤 컨텐트가 존재하는 클라이언트 영역과 함께 content area와 함께 공유됩니다. 이러한 항목이 자신의 표현을 가질 수 있도록하기 위해 MSAA의 디자이너는 OBJID_WINDOW가 전체 창을 나타내는 2 단계 구조를 선택했으며 스크롤바, 메뉴 모음, 제목 표시 줄 등을 나타내는 하위 항목이 있습니다. 선물.

그러나 액세스 가능성을 구현하는 창의 일부는 일반적으로 클라이언트 부분이므로 일반적으로 '실제'IAccessible을 얻으려면 OBJID_CLIENT를 요청해야합니다.

+0

Genius! 이제 C#과 C++ 모두에서 제대로 작동합니다. 그리고 설명에 감사드립니다. 난 이미 다른 (주로 UIA) 물건의로드를 수행하는 C# DLL에 추가하고있어 CoInitializeEx에서 OK라고 생각하므로 COM이 필 요할 때 이미이 코드에 도달했을 때 초기화되었다고 생각합니다. –

+0

Windows 10에 문제가있는 사람이 있습니까? QueryService는 IAccessible2 개체를 반환하지 않습니다. 동일한 컴파일 된 프로그램이 Windows 2003에서 정상적으로 작동합니다. – OCTAGRAM