0

次のコードがあります。

IAccessible *pAccessible = NULL;
IServiceProvider *pServProv = NULL; 
AccessibleObjectFromWindow((HWND)0x0025093A, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible);

HRESULT hr = pAccessible->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
if (SUCCEEDED(hr) && (pServProv != NULL))
{
    const GUID unused;
    ISimpleDOMDocument *pAccDoc = NULL;

    hr = pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);

    if (SUCCEEDED(hr) && (pAccDoc != NULL))
    {
        // Success
    }
    else
    {
        // Failure
    }
}

上記のハードコーディングされた HWND は、MozillaContentWindowClass のインスタンスに対するものです。

QueryService まで取得できます - AccessibleObjectFromWindow と QueryInterface の両方が成功し、NULL 以外のオブジェクトを返します。ただし、QueryService は「無効なパラメーター」を返します。IID_ISimpleDom* を使用して QueryInterface を呼び出すだけで、QueryService を使用していない他の提案を見てきましたが、これらの呼び出しは「サービスなし」エラーを返します。

Document オブジェクトに移動し、そこからノードへの参照を取得するという提案も見ましたが、それを達成する方法がよくわかりません (IAccessibility は初めてです)。

洞察に感謝します。

4

1 に答える 1

1

Mozillaが提供する Magic GUID

if (pAccChild)
{
    CComQIPtr<IServiceProvider> provider = pAccChild;
    if( provider ){
       const GUID refguid = {0x0c539790, 0x12e4, 0x11cf, 0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8};

      CComPtr<ISimpleDOMNode> node;
      provider->QueryService(refguid, IID_ISimpleDOMNode, (void**)&node);
      CComQIPtr<ISimpleDOMDocument> ffdocument = node;
      if (node) {
        ffdocument->get_URL(&DOM_string);
        if (DOM_string != 0) { 
            addressbar = (const wchar_t *)_bstr_t(DOM_string, FALSE); 
        }
      }

ここでAccessibleObjectFromWindow、プロバイダを取得するまでの間に、アクセス可能な階層を移動する必要がある場合がありますが、これは少し面倒です。

提案については、このCode Project - XMSAALibをご覧ください。

以下は、さまざまな問題をカバーするツリー ウォーキングの例です。ATL スマート ポインターを使用するようにオリジナルから変更され、いくつかのバグ修正 (または導入 ;) )

//-----------------------------------------------------------------------------
bool CXMSAALib::EnumAccessible(IAccessible *pIAccParent, IAccessibleEnumProc& lpEnumAccessibleProc )
{
    _ASSERTE(pIAccParent);

    // 2 ways to go through the children
    // * some parents will support the Enum(erator) interface where child ids may not be a contiguous sequence, and children may be returned as id or IAccessible directly
    // * others support the accChild function only where the count and ids should be contiguous.

    CComQIPtr<IEnumVARIANT> pEnum = pIAccParent;
    if( pEnum )
        pEnum->Reset();

    // get child count
    long nChildren = 0;
    if( FAILED( pIAccParent->get_accChildCount(&nChildren) ) )
        nChildren = 0;
    //TRACE(_T("nChildren=%d\n"), nChildren);

    bool bContinue = true;
    // skip 0 (self)
    for (long index = 1; (index <= nChildren) && bContinue; index++)
    {
        HRESULT hr =0;
        VARIANT varChildRef;
        VariantInit(&varChildRef);
        if (pEnum)
        {
            unsigned long nFetched = 0;
            hr = pEnum->Next(1, &varChildRef, &nFetched);
            //children may be returned as lVal id or IAccessible directly
            if (!SUCCEEDED(hr) || !nFetched )
            {
                bContinue = false;
                break;
            }
        }
        else
        {
            varChildRef.vt = VT_I4;
            varChildRef.lVal = index;
        }

        // IAccessible doesn't always allow indirect access to children that are also of type IAccessible
        // change the focus to the child element if we can
        VARIANT varChild;
        VariantInit(&varChild);
        CComPtr<IAccessible> pIAccChild;
        FocusOnChild( pIAccParent, varChildRef, pIAccChild, varChild );

        bContinue = lpEnumAccessibleProc(pIAccChild, varChild);

        if ( bContinue 
            && pIAccChild 
            && CHILDID_SELF == varChild.lVal )
        {

            bContinue = EnumAccessible(pIAccChild, lpEnumAccessibleProc);

        }

        VariantClear(&varChild);
    }

    return bContinue;
}

//-----------------------------------------------------------------------------
bool CXMSAALib::EnumAccessible(HWND hwnd, IAccessibleEnumProc& lpEnumAccessibleProc) 
{
    if (::IsWindow(hwnd))
    {
        CComPtr<IAccessible> pIAccParent;

        HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pIAccParent);
        if (SUCCEEDED(hr) && pIAccParent)
        {
            VARIANT varChild;
            VariantInit(&varChild);
            varChild.vt = VT_I4;
            varChild.lVal = CHILDID_SELF;
            if( lpEnumAccessibleProc(pIAccParent, varChild) ) {
                EnumAccessible(pIAccParent, lpEnumAccessibleProc, nLevel+1);
            }

            VariantClear(&varChild);
            return true;
        }
    }
    return false;
}

//-----------------------------------------------------------------------------
void CXMSAALib::FocusOnChild( IAccessible * pIAccParent, VARIANT &varChildRef, CComPtr<IAccessible> &pIAccChild, VARIANT &varChild ) 
{
    // get IDispatch interface for the child
    CComPtr<IDispatch> pDisp;
    if (varChildRef.vt == VT_I4)
    {
        pIAccParent->get_accChild(varChildRef, &pDisp);
    }
    else if (varChildRef.vt == VT_DISPATCH)
    {
        pDisp = varChildRef.pdispVal;
    }

    // get IAccessible interface for the child
    CComQIPtr<IAccessible> pCAcc(pDisp);

    if (pCAcc && pCAcc != pIAccParent )
    {
        VariantInit(&varChild);
        varChild.vt = VT_I4;
        varChild.lVal = CHILDID_SELF;
        pIAccChild = pCAcc;
    }
    else
    {
        pIAccChild = pIAccParent;
        varChild = varChildRef;
    }
}
于 2011-03-12T06:34:13.540 に答える