修复方案:SetProcessDPIAware 与 DPI 感知

修复只需一个 API 调用——告诉 Windows 你的应用理解高 DPI,要使用物理像素:

// C / C++ (Windows API)

SetProcessDPIAware();

// C# (.NET)

[DllImport("user32.dll")]

static extern bool SetProcessDPIAware();

SetProcessDPIAware();

// Python (ctypes)

import ctypes

ctypes.windll.user32.SetProcessDPIAware()

// Python(推荐,较新的 Windows)

import ctypes

ctypes.windll.shcore.SetProcessDpiAwareness(2) // PROCESS_PER_MONITOR_DPI_AWARE

// Python(推荐,Windows 10 1703+ 和 Windows 11)

import ctypes

DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = ctypes.c_void_p(-4)

ctypes.windll.user32.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)

调用之后,坐标函数返回的就是物理像素值而非逻辑值。pyautogui.size() 会返回 3840×2160 而不是 2560×1440。pyautogui.position() 会返回真实的像素位置。你的点击会精确落在你期望的地方。

该用哪个调用?

API行为适用场景

SetProcessDPIAware()系统级 DPI 感知。获取主显示器的物理分辨率。单显示器,统一缩放。

SetProcessDpiAwareness(2)逐显示器 DPI 感知。获取每台显示器的真实物理分辨率。多显示器混合 DPI(Windows 8.1+)。

SetProcessDpiAwarenessContext(-4)逐显示器 DPI 感知 V2。同上,额外修复了混合 DPI 下标题栏和非客户区的缩放 bug。推荐用于 Windows 10 1703+ 和 Windows 11。参见我们的多显示器坐标指南。

应用清单方式(无需写代码)

如果你在开发 Windows 应用,可以在清单文件中声明 DPI 感知,不需要调用 API:

true/pm

关于 PyAutoGUI 的完整修复方案(包括多显示器支持和截图区域偏移),参见我们的PyAutoGUI 坐标指南。