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

获取Windows单显示器缩放比例的技术咨询

获取Windows显示设置中的显示器缩放比例(.NET 6 C#)

核心解决思路:正确调用GetDpiForMonitor接口

你遇到的问题核心是没指定正确的DPI类型参数。GetDpiForMonitor返回的三个DPI值对应不同用途:

  • MDT_RAW_DPI:显示器物理硬件DPI,和系统缩放设置无关
  • MDT_ANGULAR_DPI:基于视觉角度计算的DPI,也不对应系统缩放
  • MDT_EFFECTIVE_DPI:直接对应当前系统显示设置里的缩放比例,这才是你需要的参数

系统默认100%缩放对应96DPI,缩放比例计算公式为:
缩放百分比 = (EffectiveDPI值 / 96) * 100%
比如120DPI对应125%,144DPI对应150%,完全匹配系统设置的数值。

具体实现代码

先定义必要的WinAPI P/Invoke声明:

using System;
using System.Runtime.InteropServices;

public static class DisplayScaleHelper
{
    public enum MonitorDpiType : int
    {
        MDT_EFFECTIVE_DPI = 0,
        MDT_ANGULAR_DPI = 1,
        MDT_RAW_DPI = 2
    }

    [DllImport("user32.dll")]
    public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);

    public delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [DllImport("shcore.dll")]
    public static extern int GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY);
}

再编写获取所有显示器缩放比例的方法:

public static void GetAllDisplayScales()
{
    DisplayScaleHelper.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, 
        delegate(IntPtr hMonitor, IntPtr hdcMonitor, ref DisplayScaleHelper.RECT lprcMonitor, IntPtr dwData)
        {
            if (DisplayScaleHelper.GetDpiForMonitor(hMonitor, DisplayScaleHelper.MonitorDpiType.MDT_EFFECTIVE_DPI, out uint dpiX, out uint dpiY) == 0)
            {
                // 多数情况下X/Y方向DPI一致,取任一计算即可
                double scalePercent = Math.Round((dpiX / 96.0) * 100);
                Console.WriteLine($"显示器句柄:{hMonitor},系统缩放比例:{scalePercent:N0}%");
            }
            return true;
        }, IntPtr.Zero);
}

常见误区说明

  • 不要依赖dmPelsWidth:这个值是系统缩放后的逻辑分辨率,和物理分辨率的比值虽然能算出缩放,但受应用DPI感知设置影响,不如直接取Effective DPI准确。
  • 必须指定MDT_EFFECTIVE_DPI:另外两个DPI类型是硬件或视觉相关的,和系统显示设置里的100%/125%这类缩放值完全不对应。

窗口程序可选方案

如果你的应用是带窗口的程序,也可以通过窗口句柄直接获取对应显示器的缩放:

[DllImport("user32.dll")]
public static extern uint GetDpiForWindow(IntPtr hwnd);

// 使用示例
public static double GetCurrentWindowScale(IntPtr windowHandle)
{
    uint dpi = GetDpiForWindow(windowHandle);
    return Math.Round((dpi / 96.0) * 100);
}

内容的提问来源于stack exchange,提问作者cheesemp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:42:36