如何通过Python脚本获取Windows 10/8显示器缩放比例?
获取Windows显示器缩放比例(无需开启DPI感知)
没问题!既然你不想开启DPI感知带来额外问题,那我们直接通过Windows原生API来获取缩放比例就好,下面给你基于ctypes的实现方案(你已经在用这个库,刚好适配),涵盖GetDpiForMonitor和GetScaleFactorForMonitor两种方式:
方案一:使用GetDpiForMonitor(推荐,支持Windows 8.1+)
这个API会返回指定监视器的DPI值,我们可以通过**当前DPI / 96 * 100%**来计算缩放比例(Windows默认DPI是96,对应100%缩放)。
完整代码
import ctypes from ctypes import wintypes # 定义需要的Windows API常量和结构体 user32 = ctypes.windll.user32 shcore = ctypes.windll.shcore # DPI类型常量 MDT_EFFECTIVE_DPI = 0 # 获取当前生效的DPI MDT_ANGULAR_DPI = 1 MDT_RAW_DPI = 2 # MONITORINFOEX结构体 class MONITORINFOEX(ctypes.Structure): _fields_ = [ ("cbSize", wintypes.DWORD), ("rcMonitor", wintypes.RECT), ("rcWork", wintypes.RECT), ("dwFlags", wintypes.DWORD), ("szDevice", wintypes.WCHAR * 32) ] # 监视器枚举回调函数类型 MONITORENUMPROC = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HMONITOR, wintypes.HDC, wintypes.LPRECT, wintypes.LPARAM) # 存储所有显示器的缩放比例 monitor_scales = [] def monitor_enum_proc(hMonitor, hdcMonitor, lprcMonitor, dwData): mi = MONITORINFOEX() mi.cbSize = ctypes.sizeof(MONITORINFOEX) if user32.GetMonitorInfoW(hMonitor, ctypes.byref(mi)): # 获取该显示器的DPI dpi_x = wintypes.UINT() dpi_y = wintypes.UINT() result = shcore.GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, ctypes.byref(dpi_x), ctypes.byref(dpi_y)) if result == 0: # 调用成功 scale = (dpi_x.value / 96) * 100 monitor_scales.append({ "device_name": mi.szDevice, "scale_percent": round(scale, 1), "dpi_x": dpi_x.value, "dpi_y": dpi_y.value }) return True # 枚举所有显示器 user32.EnumDisplayMonitors(None, None, MONITORENUMPROC(monitor_enum_proc), 0) # 打印结果 print("所有显示器缩放比例:") for idx, monitor in enumerate(monitor_scales, 1): print(f"显示器{idx}:") print(f" 设备名称: {monitor['device_name']}") print(f" 缩放比例: {monitor['scale_percent']}%") print(f" DPI(X/Y): {monitor['dpi_x']}/{monitor['dpi_y']}")
方案二:使用GetScaleFactorForMonitor(更直接,Windows 8.1+)
这个API直接返回缩放比例的百分比(比如150代表150%),不需要额外计算:
简化代码片段
# 接上面的枚举回调函数,替换GetDpiForMonitor部分 scale_factor = wintypes.UINT() result = shcore.GetScaleFactorForMonitor(hMonitor, ctypes.byref(scale_factor)) if result == 0: monitor_scales.append({ "device_name": mi.szDevice, "scale_percent": scale_factor.value })
关键注意事项
- 这两个API都依赖
shcore.dll,仅支持Windows 8.1及以上系统,刚好匹配你的Windows 8/10需求。 - 因为你没有开启DPI感知,系统不会自动缩放你的应用窗口,但通过这些API你能拿到真实的缩放比例,用来手动调整UI元素大小等。
- 如果是单显示器场景,你可以直接取
monitor_scales[0]的结果。
内容的提问来源于stack exchange,提问作者Torvoor
相关产品推荐
相关产品推荐

