Есть ли способ ускорить обход MSAA IAccessible?

Прямо сейчас у меня есть эта функция C++ (удалены проверки безопасности и некоторый код, чтобы сделать его более читаемым):

HRESULT WalkTreeWithAccessibleChildren(wstringstream *ss, IAccessible* pAcc, int depth)
{
    long childCount;
    long returnCount;   

    VARIANT* pArray = new VARIANT[childCount];
    hr = AccessibleChildren(pAcc, 0L, childCount, pArray, &returnCount);
    for (int x = 0; x < returnCount; x++) {
        VARIANT vtChild = pArray[x];
        Get the role and name of the component here
        // If it's an accessible object, get the IAccessible, and recurse.
        if (vtChild.vt == VT_DISPATCH) {
            IDispatch* pDisp = vtChild.pdispVal;
            IAccessible* pChild = NULL;
            hr = pDisp->QueryInterface(IID_IAccessible, (void**) &pChild);
            WalkTreeWithAccessibleChildren(ss, pChild, depth + 1);
    }
}

Для некоторых программ с относительно небольшим количеством компонентов (около 200), например. Paint.NET, это занимает около 2 полных секунд, есть ли способ ускорить эту функцию, получить все компоненты за один COM-вызов или что-то в этом роде?


person John Walters    schedule 19.06.2012    source источник


Ответы (1)


Это зависит от того, что вы пытаетесь сделать.

Если вы ищете определенный элемент, вы можете иногда использовать навигацию (accNavigate), чтобы быстрее добраться до элемента, а не просматривать все элементы.

Если вам действительно нужно получить все элементы, фоновая многопоточность работает хорошо.

Другой вариант — использовать API-интерфейс UIAutomation, который по-прежнему поддерживает все серверы IAccessible, и в него встроено более богатое кэширование и фильтрация. Посмотрите в MSDN IUIAutomationCacheRequest и его методы TreeFilter и TreeScope для получения дополнительной информации. У него также есть способ поиска определенных предметов, если вы находитесь в конкретном случае предмета.

Думайте об UIAutomation как о надмножестве IAccessible. UIAutomation доступен в Vista SP2 и выше.

person Adam Marks    schedule 22.06.2012
comment
К сожалению, использование UIAutomation не вариант (должен работать для XP с пакетом обновления 2), и accNavigate, похоже, не работает быстрее, чем то, как я получаю детей прямо сейчас (это также устарело). Спасибо за ваш ответ. Как фоновые потоки увеличат скорость выполнения? Не сделают ли они все медленнее? - person John Walters; 28.06.2012
comment
Фоновая многопоточность не ускорит общий процесс получения элементов, но иногда ее можно использовать, чтобы сделать пользовательский интерфейс более отзывчивым, чтобы что-то казалось быстрее, чем оно есть на самом деле. - person Adam Marks; 03.07.2012
comment
В документации указано что The accNavigate method is deprecated and should not be used. - person Frerich Raabe; 23.11.2012