C#计算Windows10屏幕的缩放比例

现在1920x1080以上分辨率的高分屏电脑渐渐普及了。我们会在Windows的显示设置里看到缩放比例的设置。在Windows桌面客户端的开发中,有时会想要精确计算窗口的面积或位置。然而在默认情况下,无论WinForms的Screen.Bounds.Width属性还是WPF中SystemParameters.PrimaryScreenWidth属性,以下图举例,将会返回除以150%的数值1280。而不是真实的物理分辨率1920。

接下来介绍如何获取Display resolution中显示的实际分辨率。通过如下Win32 API的调用:

        [DllImport("gdi32.dll", EntryPoint = "GetDeviceCaps", SetLastError = true)]
        public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

该方法可以获取设备的硬件信息,可以通过第二个参数nIndex来指定要查询的具体信息。例如我们要用到的以像素为单位的桌面高度DESKTOPVERTRES。

复制代码
复制代码
        enum DeviceCap
        {
            VERTRES = 10,
            PHYSICALWIDTH = 110,
            SCALINGFACTORX = 114,
            DESKTOPVERTRES = 117,

            // http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
        }
复制代码
复制代码

在获得物理像素高度后,通过计算不难得出屏幕的缩放比列。

复制代码
复制代码
        private static double GetScreenScalingFactor()
        {
            var g = Graphics.FromHwnd(IntPtr.Zero);
            IntPtr desktop = g.GetHdc();
            var physicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);

            var screenScalingFactor = 
                (double)physicalScreenHeight / Screen.PrimaryScreen.Bounds.Height;
            //SystemParameters.PrimaryScreenHeight;

            return screenScalingFactor;
        }
复制代码
复制代码

在获取屏幕缩放比例后,诸如通过Graphics类的CopyFromScreen方法来截屏,或者精确控制窗口大小和位置才得以正确实现。
其实在WinForms程序中,我们还有更简单的方式来实现类似效果。即在工程中添加app.manifest文件,将<dipAware>节点的值设为true。这样修改后,Screen.PrimaryScreen.Bounds将获得实际的物理分辨率尺寸,同时你还会发现WinForms程序不糊了。这是因为Windows默认WinForms程序不支持DPI感知,在高分屏下就直接粗暴的把窗体放大。

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>

该设置对WPF无效,WPF默认支持DPI感知功能。而从UWP开始Windows客户端技术全面支持高分屏即高DPI缩放。老旧应用程序不肯升级,以至无法支持高分屏,这锅某软背着挺冤的……
所以同学们,现在开始全面转向WinUI 3吧,这货是这么些年某软兜兜转转,客户端技术集大成者。用Windows APP SDK创建Unpackged App时,恍惚间仿佛回到了在XP上装.NET Runtime的时光。
因为Github访问时常抽风,我将示例代码在Gitee上也同步了一份:

How to get Windows display scale using C#. (github.com)
How to get Windows display scale using C#. (gitee.com)

 

 

出处:https://www.cnblogs.com/manupstairs/p/15671171.html

posted on   jack_Meng  阅读(1271)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-12-10 常用功能代码收集
2014-12-10 系列文章--数据仓库
2014-12-10 数据立方体----维度与OLAP
2014-12-10 Oracle变量的定义、赋值及使用
2014-12-10 从如何优化SQL入手,提高数据仓库的ETL效率
2014-12-10 SELECT INTO 和 INSERT INTO SELECT 两种表复制语句详解(SQL数据库和Oracle数据库的区别)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

支付宝打赏

主题色彩