我正在创建一个程序,使用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
引自Microsoft文档:
Microsoft Active Accessibility不使用逻辑坐标。以下方法和函数要么返回物理坐标,要么将它们作为参数。
IAccessible::accHitTest
IAccessible::accLocation
AccessibleObjectFromPoint
默认情况下,在非96-dpi环境中运行的Microsoft Active Accessibility客户端应用程序将无法从这些调用中获取正确的结果。例如,因为光标位置在逻辑坐标中,所以客户端不能简单地将这些坐标传递给
AccessibleObjectFromPoint
以获取光标下的元素。解决方案分为两部分:
- 使客户端应用程序“dpi-aware”。为此,请在启动时调用
SetProcessDPIAware
函数。此功能使整个进程能够识别dpi,这意味着属于该进程的所有窗口都是未缩放的。- 使用具有dpi感知功能。例如,要获取光标坐标,请调用
GetPhysicalCursorPos
函数。不要使用GetCursorPos
;它在dpi感知应用程序中的行为是未定义的。如果您的应用程序与非dpi感知应用程序执行直接跨进程通信,则可以使用
PhysicalToLogicalPoint
和LogicalToPhysicalPoint
函数在逻辑和物理坐标之间进行转换。
因此,将GetCursorPos()
改为GetPhysicalCursorPos()
解决了我的问题。