AccessibleObjectFromPoint () возвращает неверный объект - PullRequest
1 голос
/ 31 марта 2019

Я создаю программу, которая выбирает объект с помощью курсора мыши с помощью AccessibleObjectFromPoint (), однако это приводит к неверному результату.

Я наведите указатель мыши на этот значок, но вместо этого он выбирает другой значок.

Вот мой пример кода:

#include <windows.h>
#include <oleacc.h>
#include <cstdio>
#include <iostream>
#include <string>

#pragma comment(lib, "oleacc.lib")

HRESULT SelectItemAtPoint(POINT point)
{
    VARIANT varItem;
    IAccessible* pAcc;
    HRESULT hr = AccessibleObjectFromPoint(point, &pAcc, &varItem);
    if ((hr == S_OK))
    {
        hr = pAcc->accSelect((SELFLAG_TAKEFOCUS | SELFLAG_TAKESELECTION), varItem);
        VariantClear(&varItem);
        pAcc->Release();
    }
    return hr;
}

int main()
{
    CoInitialize(NULL);
    while (true)
    {
        POINT pt;
        GetCursorPos(&pt);
        printf("x: %d y: %d", pt.x, pt.y);
        SelectItemAtPoint(pt);
        Sleep(50);
    }
    return 0;
}

На изображении я завис в Unreal Engine, но вместо этого программа выбрала MATLAB. Я также проверил точки курсора. Есть ли способы как это исправить?

РЕДАКТИРОВАТЬ: я использую Windows 10 Home с Visual Studio 2017

1 Ответ

1 голос
/ 31 марта 2019

Цитируется из документации Microsoft:

Ссылка на источник

Microsoft Active Accessibility не использует логические координаты.Следующие методы и функции либо возвращают физические координаты, либо принимают их в качестве параметров.

  • IAccessible::accHitTest
  • IAccessible::accLocation
  • AccessibleObjectFromPoint

По умолчанию клиентское приложение Microsoft Active Accessibility, работающее в среде не с разрешением 96 dpi, не сможет получить правильные результаты этих вызовов.Например, поскольку позиция курсора находится в логических координатах, клиент не может просто передать эти координаты в AccessibleObjectFromPoint, чтобы получить элемент, находящийся под курсором.

Решение состоит из двух частей:

  • Сделайте клиентское приложение "dpi -ware".Для этого вызовите функцию SetProcessDPIAware при запуске.Эта функция делает весь процесс dpi-осведомленным, что означает, что все окна, принадлежащие процессу, являются немасштабируемыми.

  • Используйте функции, поддерживающие dpi.Например, чтобы получить координаты курсора, вызовите функцию GetPhysicalCursorPos.Не используйте GetCursorPos;его поведение в приложениях с поддержкой dpi не определено.

Если ваше приложение выполняет прямой межпроцессный обмен данными с приложениями, не поддерживающими dpi, возможно, вам пришлось преобразовывать логические и физические координаты с помощью функций PhysicalToLogicalPoint и LogicalToPhysicalPoint.

Таким образом, изменение GetCursorPos() на GetPhysicalCursorPos() решило мою проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...