如何获取每个显示器的缩放因子,例如 1、1.25、1.5

use*_*503 8 c# multiple-monitors class-library dpi

我知道以前曾有人问过这个问题,但我已经尝试了找到的所有答案,但似乎没有一个对我有用。答案似乎适用于单个显示器,或者需要窗口句柄,或者位于 WPF 应用程序中。我有一个没有 UI 的 C# 类库,它是从不同的语言一起调用的。

我被要求确定 C# 类库中连接到当前 PC 的每个显示器的缩放系数,例如 1、1.25、1.5 等。

我还需要提供每台显示器的分辨率和颜色深度。注册表确实保存了DpiValueWindows 10 中的 ,无论是什么。

Computer\HKEY_CURRENT_USER\Control Panel\Desktop\PerMonitorSettings
Run Code Online (Sandbox Code Playgroud)

但是我不知道如何将它们映射到 aScreen以获得返回的匹配分辨率

System.Windows.Forms.Screen.AllScreens
Run Code Online (Sandbox Code Playgroud)

那么有人有办法获取这些信息吗?

use*_*503 17

我相信我终于(经过长时间的搜索)找到了一个有效的答案,它甚至可以在我的高 DPI Surface Book 2 屏幕上工作。我已经尽可能地测试了它,到目前为止它总是返回正确的值。

这就是我的做法,感谢过去发布我从中收集到的代码片段的人。

首先,您需要一个结构来调用 user32.dll 中的 EnumDisplaySettings

    [StructLayout(LayoutKind.Sequential)]
    public struct DEVMODE
    {
        private const int CCHDEVICENAME = 0x20;
        private const int CCHFORMNAME = 0x20;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmDeviceName;
        public short dmSpecVersion;
        public short dmDriverVersion;
        public short dmSize;
        public short dmDriverExtra;
        public int dmFields;
        public int dmPositionX;
        public int dmPositionY;
        public ScreenOrientation dmDisplayOrientation;
        public int dmDisplayFixedOutput;
        public short dmColor;
        public short dmDuplex;
        public short dmYResolution;
        public short dmTTOption;
        public short dmCollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmFormName;
        public short dmLogPixels;
        public int dmBitsPerPel;
        public int dmPelsWidth;
        public int dmPelsHeight;
        public int dmDisplayFlags;
        public int dmDisplayFrequency;
        public int dmICMMethod;
        public int dmICMIntent;
        public int dmMediaType;
        public int dmDitherType;
        public int dmReserved1;
        public int dmReserved2;
        public int dmPanningWidth;
        public int dmPanningHeight;
    }
Run Code Online (Sandbox Code Playgroud)

然后需要声明外部函数调用

[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
Run Code Online (Sandbox Code Playgroud)

然后你需要用它来计算屏幕缩放比例

            Screen[] screenList = Screen.AllScreens;

            foreach (Screen screen in screenList)
            {
                DEVMODE dm = new DEVMODE();
                dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
                EnumDisplaySettings(screen.DeviceName, -1, ref dm);

                var scalingFactor = Math.Round(Decimal.Divide(dm.dmPelsWidth, screen.Bounds.Width), 2);
            }
Run Code Online (Sandbox Code Playgroud)

希望其他人觉得这很有用。