如何使用C#获取Windows系统的屏幕缩放比例
屏幕缩放比例获取方案(光学系统校准应用场景)
问题核心
开发光学系统校准应用时,需获取系统设置中的屏幕缩放比例。现有尝试(user32.dll/Shcore.dll/Control.AutoScaleFactor等)仅能拿到应用缩放后的虚拟DPI或100%比例(值为1),无法获取物理DPI及正确缩放比例,需解决直接获取或通过DPI计算的方法。
两种可行解决路径
1. 直接通过DLL获取缩放比例
无需计算DPI,用Shcore.dll的GetScaleFactorForMonitor函数可直接拿到缩放百分比(如100、125、150等):
using System.Runtime.InteropServices; using System.Windows.Forms; public class ScreenScaleUtil { [DllImport("Shcore.dll")] private static extern int GetScaleFactorForMonitor(IntPtr hmonitor, out uint scale); [DllImport("User32.dll")] private static extern IntPtr GetPrimaryMonitor(); // 获取主屏幕缩放比例(返回值为百分比数值,如125对应125%) public static uint GetPrimaryScreenScale() { IntPtr primaryMonitor = GetPrimaryMonitor(); GetScaleFactorForMonitor(primaryMonitor, out uint scale); return scale; } // 按钮点击示例 private void ShowScaleBtn_Click(object sender, EventArgs e) { uint scale = GetPrimaryScreenScale(); MessageBox.Show($"屏幕缩放比例:{scale}%"); } }
2. 基于DPI计算缩放比例
若需通过DPI推导,需区分两类DPI:
- 物理DPI(RawDpi):屏幕硬件的实际DPI,通过
GetDpiForMonitor指定MonitorDpiType.RawDpi获取 - 有效DPI(EffectiveDpi):系统缩放后的DPI,对应
MonitorDpiType.EffectiveDpi
缩放比例公式:缩放比例 = 有效DPI / 96(96是Windows默认100%缩放的基准DPI)
修正你之前的错误代码(核心是获取有效显示器句柄,而非IntPtr.Zero):
using System.Runtime.InteropServices; using System.Windows.Forms; public class DpiScaleUtil { [DllImport("Shcore.dll")] private static extern int GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY); [DllImport("User32.dll")] private static extern IntPtr GetPrimaryMonitor(); private enum MonitorDpiType { EffectiveDpi = 0, AngularDpi = 1, RawDpi = 2, } // 计算缩放比例(返回小数,如1.25对应125%) public static double CalculateScaleFactor() { IntPtr primaryMonitor = GetPrimaryMonitor(); GetDpiForMonitor(primaryMonitor, MonitorDpiType.EffectiveDpi, out uint dpiX, out _); return dpiX / 96.0; } private void ShowPPI_Click(object sender, EventArgs e) { double scale = CalculateScaleFactor(); MessageBox.Show($"屏幕缩放比例:{scale:P0}"); // 格式化显示为百分比 } }
关键注意事项
- 必须获取有效显示器句柄:之前代码用
IntPtr.Zero无效,需通过GetPrimaryMonitor或MonitorFromWindow(针对当前窗口所在显示器)获取句柄 - 确保应用DPI感知:若应用未标记为DPI感知,系统会自动缩放窗口,此时获取的DPI为虚拟值。需在应用清单中添加:
<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings> </application>
内容的提问来源于stack exchange,提问作者Simon Dengler
相关产品推荐
相关产品推荐

