WPF 获取屏幕缩放比例

首先,这里获取屏幕缩放比例的思路是    屏幕缩放比例 = 屏幕逻辑高度 / 屏幕实际高度

其中屏幕的实际高度可直接通过 SystemParameters.PrimaryScreenHeight 获得;

而对于屏幕逻辑高度,由于在WPF中,不像winform那样可以通过System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height直接获取,且在WPF项目中一般也不建议直接引用winfrom

因此,本文主要考虑调用相关Windows API,通过其获取屏幕的逻辑高度,具体代码如下

1.相关Windows API代码

public static class WindowsMonitorAPI
    {
        private const string User32 = "user32.dll";

        [DllImport(User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out]MONITORINFOEX info);

        [DllImport(User32, ExactSpelling = true)]
        [ResourceExposure(ResourceScope.None)]
        public static extern bool EnumDisplayMonitors(HandleRef hdc, COMRECT rcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);

        public delegate bool MonitorEnumProc(IntPtr monitor, IntPtr hdc, IntPtr lprcMonitor, IntPtr lParam);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        public class MONITORINFOEX
        {
            internal int cbSize = Marshal.SizeOf(typeof(MONITORINFOEX));
            internal RECT rcMonitor = new RECT();
            internal RECT rcWork = new RECT();
            internal int dwFlags = 0;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            internal char[] szDevice = new char[32];
        }

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

            public RECT(Rect r)
            {
                left = (int)r.Left;
                top = (int)r.Top;
                right = (int)r.Right;
                bottom = (int)r.Bottom;
            }
        }

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

        public static readonly HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
    }

2.获取屏幕缩放比例Helper

public class ScreenHelper
    {
        /// <summary>
        /// 获取缩放比例
        /// </summary>
        /// <returns></returns>
        public static double GetScalingRatio()
        {
            var logicalHeight = GetLogicalHeight();
            var actualHeight = GetActualHeight();

            if (logicalHeight > 0 && actualHeight > 0)
            {
                return logicalHeight / actualHeight;
            }

            return 1;
        }

        private static double GetActualHeight()
        {
            return SystemParameters.PrimaryScreenHeight;
        }

        private static double GetLogicalHeight()
        {
            var logicalHeight = 0.0;

            WindowsMonitorAPI.MonitorEnumProc proc = (m, h, lm, lp) =>
            {
                WindowsMonitorAPI.MONITORINFOEX info = new WindowsMonitorAPI.MONITORINFOEX();
                WindowsMonitorAPI.GetMonitorInfo(new HandleRef(null, m), info);

                //是否为主屏
                if ((info.dwFlags & 0x00000001) != 0)
                {
                    logicalHeight = info.rcMonitor.bottom - info.rcMonitor.top;
                }

                return true;
            };
            WindowsMonitorAPI.EnumDisplayMonitors(WindowsMonitorAPI.NullHandleRef, null, proc, IntPtr.Zero);

            return logicalHeight;
        }
    }

3.调用

System.Windows.MessageBox.Show($"当前缩放比例为{ScreenHelper.GetScalingRatio()}%");

 

    原文作者:麦琼辉
    原文地址: https://blog.csdn.net/maizi314/article/details/104841203
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞