gpt4 book ai didi

winapi - 可以在每个 session 的基础上以编程方式启用/禁用 DPI 缩放吗?

转载 作者:行者123 更新时间:2023-12-04 13:36:51 30 4
gpt4 key购买 nike

我的应用程序恰好是使用 Python 编写的,它使用包装 SDL 的 pygame,但我想这可能是与 Windows API 相关的更普遍的问题。

在我的一些 Python 应用程序中,即使在高分辨率下,我也希望在 Windows 10 下进行逐像素控制。例如,我希望能够确保如果我的 Surface Pro 3 具有 2160x1440 的原始分辨率,那么我可以进入具有这些尺寸的全屏模式并呈现完全具有这些尺寸的全屏图像。

这样做的障碍是“DPI 缩放”。默认情况下,在 Windows 的设置 -> 显示下,“更改文本、应用程序和其他项目的大小”的值为“150%(推荐)”,结果是我只能看到我的图像的 2/3。我发现了如何解决这种行为......

  • 在系统范围内,通过将该 slider 向下移动到 100%(但对于大多数其他应用程序来说,这是 undesirable)
  • 只为 python.exepythonw.exe ,通过转到这些可执行文件的“属性”对话框、“兼容性”选项卡,然后单击“在高 DPI 设置上禁用显示缩放”。我可以为我一个人或为所有用户执行此操作。我还可以通过以编程方式在注册表中设置适当的键来自动执行此过程。或通过 .exe.manifest文件(这似乎也需要更改全局设置,以更喜欢外部 list ,可能会对其他应用程序产生副作用)。

  • 我的问题是:在我打开图形窗口之前,我可以在每次启动的基础上从我的程序内部执行此操作吗?我,或任何使用我的软件的人,不一定希望为所有 Python 应用程序启用此设置——我们可能只是在运行特定的 Python 程序时才需要它。我想可能有一个 winapi调用(或在 SDL 中失败,由 pygame 包装的东西)可以实现这一点,但到目前为止,我的研究是一片空白。

    最佳答案

    这是我正在寻找的答案,基于 IInspectable 和 andlabs 的评论(非常感谢):

      import ctypes

    # Query DPI Awareness (Windows 10 and 8)
    awareness = ctypes.c_int()
    errorCode = ctypes.windll.shcore.GetProcessDpiAwareness(0, ctypes.byref(awareness))
    print(awareness.value)

    # Set DPI Awareness (Windows 10 and 8)
    errorCode = ctypes.windll.shcore.SetProcessDpiAwareness(2)
    # the argument is the awareness level, which can be 0, 1 or 2:
    # for 1-to-1 pixel control I seem to need it to be non-zero (I'm using level 2)

    # Set DPI Awareness (Windows 7 and Vista)
    success = ctypes.windll.user32.SetProcessDPIAware()
    # behaviour on later OSes is undefined, although when I run it on my Windows 10 machine, it seems to work with effects identical to SetProcessDpiAwareness(1)

    认识水平 are defined如下:

    typedef enum _PROCESS_DPI_AWARENESS { 
    PROCESS_DPI_UNAWARE = 0,
    /* DPI unaware. This app does not scale for DPI changes and is
    always assumed to have a scale factor of 100% (96 DPI). It
    will be automatically scaled by the system on any other DPI
    setting. */

    PROCESS_SYSTEM_DPI_AWARE = 1,
    /* System DPI aware. This app does not scale for DPI changes.
    It will query for the DPI once and use that value for the
    lifetime of the app. If the DPI changes, the app will not
    adjust to the new DPI value. It will be automatically scaled
    up or down by the system when the DPI changes from the system
    value. */

    PROCESS_PER_MONITOR_DPI_AWARE = 2
    /* Per monitor DPI aware. This app checks for the DPI when it is
    created and adjusts the scale factor whenever the DPI changes.
    These applications are not automatically scaled by the system. */
    } PROCESS_DPI_AWARENESS;

    级别 2 听起来最适合我的目标,但如果系统分辨率/DPI 缩放没有变化,级别 1 也可以工作。
    SetProcessDpiAwareness将失败并显示 errorCode = -2147024891 = 0x80070005 = E_ACCESSDENIED如果之前已经为当前进程调用过它(包括在进程启动时由系统调用,由于注册表项或 .manifest 文件)

    关于winapi - 可以在每个 session 的基础上以编程方式启用/禁用 DPI 缩放吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44398075/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com