【问题标题】:Finding virtual screen width using multiple monitors and different DPI使用多个显示器和不同 DPI 查找虚拟屏幕宽度
【发布时间】:2021-03-02 06:15:42
【问题描述】:

我正在尝试使用SendInput 模拟鼠标输入,但是如果有多个监视器,我需要确定虚拟屏幕宽度,以设置dxdy 值,例如:

dx = (x * 65536) / SystemInformation.VirtualScreen.Width;
dy = (y * 65536) / SystemInformation.VirtualScreen.Height;

问题在于显示器显然具有不同的 DPI 值,从而导致虚拟大小不正确。 作为参考,SystemInformation.VirtualScreen.Size 和对GetSystemMetrics(SM_CXVIRTUALSCREEN) 的调用都返回相同的错误值。

我尝试使用GetSystemMetricsForDPI 也没有成功。

【问题讨论】:

  • @Sonts 没有。您正在谈论缩放应用程序。我正在尝试计算标题中所述的虚拟屏幕大小。
  • 这些 DPI 虚拟化恶作剧不仅会扩展应用程序的 GUI,还会影响许多操作系统 API,包括 SystemInformation.VirtualScreen.Size 和 GetSystemMetrics。当应用声明它支持每个显示器的 DPI 时,Windows 不会再谎报屏幕尺寸,这些 API 会返回真实的硬件像素。
  • 等等,这确实解决了问题,但为什么呢?示例清单状态:Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher DPIs. 它还指出 WPF 应用程序默认具有此功能,但我实际上是在使用 SystemParameters.VirtualScreenWidth 的 WPF 应用程序中执行此操作,结果不正确。我会再看看这个。

标签: c# sendinput virtual-screen


【解决方案1】:

默认情况下,Windows 将 DPI 虚拟化应用于所有坐标。

如果您有 2 台显示器,左侧的辅助 FullHD 具有 100% 缩放比例,右侧主要 4k 具有 200% DPI 缩放比例,屏幕配置 API 会告诉您桌面有 3840x1080 像素,第二个来自 [ -1920 .. 0],第一个 [0 .. 1920]。要在左显示器中心模拟鼠标输入,您应该使用 X 坐标 -960 * 0x10000 / 1920 = -32768 不带 MOUSEEVENTF_VIRTUALDESK 标志,或 960 * 0x10000 / 3840 = 16384 带 MOUSEEVENTF_VIRTUALDESK 标志

您可以告诉 Windows 停止在您的应用程序中使用 DPI,with a manifest

如果您在同一台计算机上执行此操作,屏幕配置 API 会告诉您桌面有 5760x2160 像素,第二个是相同的,在 [-1920 .. 0 ],第一个 [0 .. 3840 ]。在这种情况下,要将鼠标输入发送到左侧显示器的中心,您应该使用 X 坐标 -960 * 0x10000 / 3840 = -16384 不带 MOUSEEVENTF_VIRTUALDESK 标志,或 960 * 0x10000 / 5760 = 10923 带 MOUSEEVENTF_VIRTUALDESK 标志。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 2013-07-18
    • 2014-03-27
    • 2016-01-05
    • 2012-12-01
    相关资源
    最近更新 更多