wpf 捕获系统显示设置变更

 Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;

//变更后回调

 private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
        {
//获取变更后的信息
//引用Screen需要工程文件添加<UseWindowsForms>true</UseWindowsForms>
[wpf引用winform](https://www.cnblogs.com/ives/p/15339170.html)
            using (System.Drawing.Graphics currentGraphics = System.Drawing.Graphics.FromHwnd(new WindowInteropHelper(this).Handle))
            {
                double dpixRatioX = currentGraphics.DpiX / 96;
                double dpixRatioY = currentGraphics.DpiY / 96;

                var intPtr = new WindowInteropHelper(this).Handle;//获取当前窗口的句柄
                var screen = System.Windows.Forms.Screen.FromHandle(intPtr);//获取当前屏幕
                
            }
        }

获取屏幕DPI

/// <summary>
        ///  <paramref name="visual"/> 获取一个在显示设备上的尺寸相对于自身尺寸的缩放比。
        /// </summary>
        public static Size GetScalingRatioToDevice(this Visual visual)
        {
            return visual.GetTransformInfoToDevice().size;
        }

        /// <summary>
        ///  <paramref name="visual"/> 获取一个在显示设备上的尺寸相对于自身尺寸的缩放比和旋转角度(顺时针为正角度)。
        /// </summary>
        public static (Size size, double angle) GetTransformInfoToDevice(this Visual visual)
        {
            if (visual == null) throw new ArgumentNullException(nameof(visual));

            // 计算此 Visual 在 WPF 窗口内部的缩放(含 ScaleTransform 等)。
            var root = VisualRoot(visual);
            var transform = ((MatrixTransform)visual.TransformToAncestor(root)).Value;
            // 计算此 WPF 窗口相比于设备的外部缩放(含 DPI 缩放等)。
            var ct = PresentationSource.FromVisual(visual)?.CompositionTarget;
            if (ct != null)
            {
                transform.Append(ct.TransformToDevice);
            }
            // 如果元素有旋转,则计算旋转分量。
            var unitVector = new Vector(1, 0);
            var vector = transform.Transform(unitVector);
            var angle = Vector.AngleBetween(unitVector, vector);
            transform.Rotate(-angle);
            // 计算考虑了旋转的综合缩放比。
            var rect = new Rect(new Size(1, 1));
            rect.Transform(transform);

            return (rect.Size, angle);
        }

        /// <summary>
        /// 寻找一个 <see cref="Visual"/> 连接着的视觉树的根。
        /// 通常,如果这个 <see cref="Visual"/> 显示在窗口中,则根为 <see cref="Window"/>;
        /// 不过,如果此 <see cref="Visual"/> 没有显示出来,则根为某一个包含它的 <see cref="Visual"/>。
        /// 如果此 <see cref="Visual"/> 未连接到任何其它 <see cref="Visual"/>,则根为它自身。
        /// </summary>
        private static Visual VisualRoot(Visual visual)
        {
            if (visual == null) throw new ArgumentNullException(nameof(visual));

            var root = visual;
            var parent = VisualTreeHelper.GetParent(visual);
            while (parent != null)
            {
                if (parent is Visual r)
                {
                    root = r;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }
            return root;
        }
posted @ 2021-10-09 13:34  Hey,Coder!  阅读(170)  评论(0编辑  收藏  举报