【问题标题】:Query Windows 10/8 Monitor Scaling from Python Script?从 Python 脚本查询 Windows 10/8 监视器缩放?
【发布时间】:2018-05-09 12:54:45
【问题描述】:

我在 python 3.6 中编写了一个应用程序,并想运行一个命令来查看显示器在 Windows 10 或 8 中的当前缩放比例 - 类似于以下返回屏幕分辨率的方式:

user32 = ctypes.windll.user32
screensize_l = user32.GetSystemMetrics(0)
screensize_w = user32.GetSystemMetrics(1)

我知道最简单的方法可能是让我的应用程序了解 DPI,但这样做会导致我的应用程序出现许多其他问题 - 所以我想避免使用此选项。

我查看了 Windows 文档并认为“GetDpiForMonitor”或“GetScaleFactorForMonitor”可能是我正在寻找的,但不知道如何实现这些命令。

我已经使用了 win32api 和 ctypes,所以任何依赖于其中任何一个的东西都可以 - 任何帮助都将不胜感激!

【问题讨论】:

  • 我解决了我自己的问题,我煞费苦心地让我的程序根据 user32.GetSystemMetrics(0) 和 user32.GetSystemMetrics(1) 返回的屏幕大小重新缩放所有固定元素。我刚刚计算了一个与我最初预期的屏幕尺寸相关的调整因子。

标签: python windows winapi scale scaling


【解决方案1】:

在 Windows 10 上,以下代码(您需要 pywin32):

import ctypes
import win32api

PROCESS_PER_MONITOR_DPI_AWARE = 2
MDT_EFFECTIVE_DPI = 0

def print_dpi():
    shcore = ctypes.windll.shcore
    monitors = win32api.EnumDisplayMonitors()
    hresult = shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
    assert hresult == 0
    dpiX = ctypes.c_uint()
    dpiY = ctypes.c_uint()
    for i, monitor in enumerate(monitors):
        shcore.GetDpiForMonitor(
            monitor[0].handle,
            MDT_EFFECTIVE_DPI,
            ctypes.byref(dpiX),
            ctypes.byref(dpiY)
        )
        print(
            f"Monitor {i} (hmonitor: {monitor[0]}) = dpiX: {dpiX.value}, dpiY: {dpiY.value}"
        )


if __name__ == "__main__":
    print_dpi()

在我的机器上使用 3 个监视器和 1 个缩放为 125% 提供以下输出:

Monitor 0 (hmonitor: <PyHANDLE:65539>) = dpiX: 96, dpiY: 96
Monitor 1 (hmonitor: <PyHANDLE:65537>) = dpiX: 120, dpiY: 120
Monitor 2 (hmonitor: <PyHANDLE:65541>) = dpiX: 96, dpiY: 96

如果您不想将自己的应用程序设置为每台显示器支持 dpi,您可以尝试使用 multiprocessing 模块在另一个进程中启动上述代码的一些变体并检索结果。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2021-10-20
    • 2021-06-19
    相关资源
    最近更新 更多