AccessibleObjectFromPoint()返回不正确的对象

问题描述 投票:1回答:1

我正在创建一个程序,使用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;
}

在我在虚幻引擎中徘徊的图像中,程序选择了MATLAB。我还检查了光标点。有什么方法可以解决这个问题?

编辑:我在Visual Studio 2017中使用Windows 10 Home

c++ winapi com
1个回答
1
投票

引自Microsoft文档:

Source Link

Microsoft Active Accessibility不使用逻辑坐标。以下方法和函数要么返回物理坐标,要么将它们作为参数。

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

默认情况下,在非96-dpi环境中运行的Microsoft Active Accessibility客户端应用程序将无法从这些调用中获取正确的结果。例如,因为光标位置在逻辑坐标中,所以客户端不能简单地将这些坐标传递给AccessibleObjectFromPoint以获取光标下的元素。

解决方案分为两部分:

  • 使客户端应用程序“dpi-aware”。为此,请在启动时调用SetProcessDPIAware函数。此功能使整个进程能够识别dpi,这意味着属于该进程的所有窗口都是未缩放的。
  • 使用具有dpi感知功能。例如,要获取光标坐标,请调用GetPhysicalCursorPos函数。不要使用GetCursorPos;它在dpi感知应用程序中的行为是未定义的。

如果您的应用程序与非dpi感知应用程序执行直接跨进程通信,则可以使用PhysicalToLogicalPointLogicalToPhysicalPoint函数在逻辑和物理坐标之间进行转换。

因此,将GetCursorPos()改为GetPhysicalCursorPos()解决了我的问题。

© www.soinside.com 2019 - 2024. All rights reserved.