AccessibleObjectFromPoint()返回不正确的对象

时间:2019-03-31 07:00:03

标签: c++ winapi com

我正在创建一个使用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。 我还检查了光标点。 有什么办法解决这个问题吗?

编辑:我将Windows 10 Home与Visual Studio 2017一起使用

1 个答案:

答案 0 :(得分:1)

引自Microsoft文档:

Source Link

  

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

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

默认情况下,Microsoft Active   在非96 dpi环境中运行的辅助功能客户端应用程序   将无法从这些调用中获得正确的结果。对于   例如,由于光标位置在逻辑坐标中,因此   客户不能简单地将这些坐标传递给   AccessibleObjectFromPoint来获取位于   光标。

     

解决方案分为两部分:

     
      
  • 使客户端应用程序具有“ dpi意识”。为此,请致电   SetProcessDPIAware在启动时起作用。该功能使整个   可识别dpi的进程,这意味着属于该进程的所有窗口   不缩放。

  •   
  • 使用可识别dpi的功能。例如,获得   光标坐标,请调用GetPhysicalCursorPos函数。不使用   GetCursorPos;它在dpi感知的应用程序中的行为是不确定的。

  •   
     

如果   您的应用程序与   不支持dpi的应用程序,您可能已在逻辑和   使用PhysicalToLogicalPoint和   LogicalToPhysicalPoint个功能。

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