Get_accChildCount returns 0 when it should not

I am trying to list IE tabs from an extension and from a standalone application. For one of the nodes, the MSAA get_accChildCountreturns 0 when called from the extension, while it should return 1 according to the inspectcall from the stand-alone application.

  • The problem was described earlier in StackOverflow, but it was solved with a hack that does not work for me. /clrand /MTincompatible.
  • There was also a topic on MSDN with the same problem. There is no single answer.
  • If you run IE with administrator privileges, it works correctly.
  • The API monitor shows several thousand calls in a minimal example, and it is not clear which of these are connected. Below is a minimal example.

What are the undocumented cases where it get_accChildCountreturns an incorrect count of children?

What other method can I use to activate bookmarks by URL in most versions of IE?

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <atltypes.h>
#include <atlsafe.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>

#include <iostream>
#include <string>
#include <vector>
#include <boost/format.hpp>
#include <fstream>
using namespace std;

CComPtr<IAccessible> get_acc_by_hwnd(HWND hwnd) {
    CComPtr<IAccessible> ret;
    HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, (void**) &ret);
    if (FAILED(hr) || !ret) {
        wcout << L"Accessible::Accessible invalid hwnd" << endl;
    }
    return ret;
}

std::vector<CComPtr<IAccessible>> get_acc_children(CComPtr<IAccessible> acc) {
    std::vector<CComPtr<IAccessible>> ret;
    long count;
    if (FAILED(acc->get_accChildCount(&count))) return ret;
    long count_obtained = 0;
    if (!count) return ret;
    std::vector<CComVariant> accessors(count);
    if (FAILED(::AccessibleChildren(acc, 0, count, &*accessors.begin(), &count_obtained))) return ret;
    accessors.resize(count_obtained);
    for (auto vtChild : accessors) {
        if (vtChild.vt != VT_DISPATCH) continue;
        CComQIPtr<IAccessible> pChild = vtChild.pdispVal;
        if (pChild) ret.push_back(pChild);
    }
    return ret;
}

bool is_client(CComPtr<IAccessible> acc) {
    CComVariant var;
    HRESULT hr = acc->get_accRole(CComVariant(CHILDID_SELF), &var);
    return SUCCEEDED(hr) && var.vt == VT_I4 && var.lVal == 0xA;
}

std::wstring get_descr(CComPtr<IAccessible> acc) {
    CComBSTR str;
    HRESULT hr = acc->get_accDescription(CComVariant(CHILDID_SELF), &str);
    return SUCCEEDED(hr) && str ? std::wstring(str) : L"";
}

int main() {
    ::CoInitialize(nullptr);
    _setmode(_fileno(stdout), _O_U16TEXT);

    // put HWND of the window that contains tab labels
    // it hardcoded to minimize quantity of API calls
    HWND hwnd = reinterpret_cast<HWND>(0x002D0696);
    CComPtr<IAccessible> iaccessible;
    HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, (void**) &iaccessible);
    if (FAILED(hr) || !iaccessible) {
        wcout << L"AccessibleBrowser::activate_tab " L"failed to get IAccessible for IE" << endl;
        return EXIT_FAILURE;
    }

    wstring const sentinel = L"\r\n";
    for (auto child : get_acc_children(iaccessible)) if (is_client(child)) {
        for (auto child1 : get_acc_children(child)) { // fails here in extension
            for (auto child2 : get_acc_children(child1)) {
                std::wstring descr = get_descr(child2);
                auto pos = descr.find(sentinel);
                if (pos == string::npos) continue;
                auto tab_url = descr.substr(pos + sentinel.size());
                wcout << tab_url << endl;
            }
        }
    }
}
+1
source share
1 answer

I stumbled into your program for a while, not having much for it. Perhaps I realized too late that he should not reproduce the problem :( I can give only some useful hints so that you can look under the right kind of rock.

but it was solved with a hack that doesn't work for me

, CoInitialize/Ex(). . /clr build , CLR . , CoInitialize(). , - , 0 accobjects. , .

, , COM- COM. DirectX - , UIAutomation . , , COM. , , DirectUIHWnd .

, CoInitialize(), IE, .

IE , .

. VS, . , IE. , IE IE. , , , , , . Google " IE " , , .

+2

Source: https://habr.com/ru/post/1017214/


All Articles