我有一个设置SetWindowsHookEx(WH_MOUSE_LL ,,,)右键单击钩子的进程。我的进程设置为在窗口10.0.10586上识别DPI系统,在两个监视器上以150%的比例缩放。这是通过调用SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)来设置的。
我的问题场景是Office 2007是DPI不知道的,所以让我们将MS Word放在屏幕的右边四分之一处。右键单击右下方任务栏上方,鼠标钩子发送坐标1279,675 - 缩放到Word。然后我右键单击视觉工作室(DPI识别),屏幕上几乎四分之三,鼠标钩子发送我的坐标,例如,来自Visual Studio的1279,1008。因此,如果我在屏幕上方点击更高,我可能会得到相同的1279,675。
我的过程是通过调用WindowFromPoint API来尝试确定哪个窗口就在这一点上,但在这种情况下,这显然会失败,因为两个应用程序" share"同一点。
是否可以强制鼠标挂钩始终发送原始物理坐标而不是那些缩放到DPI无意识应用程序的坐标?如果是的话,怎么样?或者,是否有其他方法可以从鼠标钩子中确定hWnd或processID?
答案 0 :(得分:0)
Microsoft在10.0.14393中修复了它。
除非在LTSB 10.0.10240上,否则您的客户网络中应该没有任何内容,只有较低的内部版本号。
这是解决方案:DPI aware screen capture
答案 1 :(得分:-1)
由于该进程可识别DPI,因此在鼠标钩子回调处理程序中调用GetCursorPos()始终会获取原始物理坐标,而不是缩放到应用程序的逻辑坐标。只需丢弃传递给鼠标回调的坐标。
已于2016年9月30日添加
值得一提的是,虽然GetMessagePos似乎很可能,但如果进程不是dpi虚拟化,它只会返回正确的坐标。
e.g。
VOID MessagePump()
{
MSG messageGet = { 0 };
DWORD dwPos;
POINTS p;
while (GetMessage(&messageGet,NULL,0,0))
{
dwPos = GetMessagePos();
p = MAKEPOINTS( dwPos );
TranslateMessage( &messageGet );
DispatchMessage( &messageGet );
}
}
在GetMessage()调用期间调用Mouse回调处理程序,但是这不会获取正确的物理坐标,其中DPI虚拟化对于进程是活动的。例如物理x = 1909,y = 1072返回1091,612,缩放率为175%,虽然算术上是正确的,但并不是所需要的。