【问题标题】:High DPI scaling, mouse hooks and WindowFromPoint高 DPI 缩放、鼠标挂钩和 WindowFromPoint
【发布时间】:2016-09-24 14:41:11
【问题描述】:

我有一个设置SetWindowsHookEx(WH_MOUSE_LL, , ,) 右键单击​​钩子的进程。我的进程在 Window 10.0.10586 上设置为 DPI 系统感知,在两个显示器上以 150% 的比例缩放。这是通过调用SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE) 设置的。

我的问题场景是例如Office 2007 不知道 DPI,所以让我们将 MS Word 放在屏幕的右四分之一。右击右下角任务栏上方,鼠标钩子发送坐标 1279, 675 - 缩放到 Word。然后我右键单击视觉工作室(DPI 感知),在屏幕上将近四分之三,鼠标钩向我发送坐标,例如1279、1008 来自 Visual Studio。因此,如果我在屏幕上方单击,我可能会得到相同的 1279、675。

我的进程试图通过调用WindowFromPoint API 来确定该点所在的窗口,但在这种情况下这显然会失败,因为两个应用程序“共享”同一点。

是否可以强制鼠标挂钩始终发送原始物理坐标,而不是那些缩放到 DPI 不感知应用程序的坐标?如果是这样,如何?或者,是否有其他方法可以通过鼠标钩子确定hWndprocessID

【问题讨论】:

    标签: c++ windows winapi dpi setwindowshookex


    【解决方案1】:

    Microsoft 在 10.0.14393 中修复了它。

    除非它们在 LTSB 10.0.10240 上,否则现在您的客户网络中应该没有任何具有较低内部版本号的东西。

    这是解决方案:DPI aware screen capture

    【讨论】:

      【解决方案2】:

      因为进程是 DPI 感知的,所以在鼠标挂钩回调处理程序中调用 GetCursorPos() 总是获取原始物理坐标,而不是缩放到应用程序的逻辑坐标。只需丢弃传递给鼠标回调的坐标。

      于 2016 年 9 月 30 日添加

      尽管 GetMessagePos 看起来很可能,但它仅在进程未进行 dpi 虚拟化时才返回正确的坐标,这一点毫无价值。

      例如

      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() 调用期间调用鼠标回调处理程序,但这不会获取正确的物理坐标,其中 DPI 虚拟化对进程处于活动状态。例如物理 x = 1909, y = 1072 以 175% 的缩放比例返回 1091, 612,虽然算术上正确,但不是必需的。

      【讨论】:

      • 听起来是个坏主意。调用 GetCursorPos 时,光标可能在别处。
      • 这是迄今为止我能想到的最好的,而且似乎几乎是瞬间完成的,但我愿意接受任何更好的建议。
      • GetMessagePos 可能更合适。
      • 我今天试了GetMessagePos,结果没用。它们根本不对应。
      • 看到SetProcessDpiAwareness 是在 Windows 8.1 中引入的,因此相对于 Windows 7 的行为会发生变化,这是预期的结果。由于我们看不到您的代码,因此无法知道您是否正确提取了鼠标位置。文档告诉你怎么做。
      猜你喜欢
      • 2018-08-07
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      相关资源
      最近更新 更多