AccessibleObjectFromPoint() returns 一个不正确的对象

AccessibleObjectFromPoint() returns an incorrect object

我正在创建一个程序,该程序使用 AccessibleObjectFromPoint() 通过鼠标光标选择对象,但是它产生了不正确的结果。

I hovered the mouse at this icon but it selects a different icon instead.

这是我的示例代码:

#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

引自微软文档:

Source Link

Microsoft Active Accessibility does not use logical coordinates. The following methods and functions either return physical coordinates or take them as parameters.

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

By default, an Microsoft Active Accessibility client application running in a non-96-dpi environment will not be able to obtain correct results from these calls. For example, because the cursor position is in logical coordinates, the client cannot simply pass these coordinates to AccessibleObjectFromPoint to obtain the element that is under the cursor.

The solution is in two parts:

  • Make the client application "dpi-aware". To do this, call the SetProcessDPIAware function at startup. This function makes the entire process dpi-aware, meaning that all windows that belong to the process are unscaled.

  • Use functions that are dpi-aware. For example, to get cursor coordinates, call the GetPhysicalCursorPos function. Do not use GetCursorPos; its behavior in dpi-aware applications is undefined.

If your application performs direct cross-process communication with non-dpi-aware applications, you may have convert between logical and physical coordinates by using the PhysicalToLogicalPoint and LogicalToPhysicalPoint functions.

所以将 GetCursorPos() 更改为 GetPhysicalCursorPos() 解决了我的问题。