You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:02:49