• 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

    您的资助是我最大的动力!
    金额随意,欢迎来赏!
    款后有任何问题请给我留言。

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我。(●'◡'●)

    如果对你有所帮助,赞助一杯咖啡!打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!

  • 相关阅读:
    margin+absolute布局:右栏固定主内容自适应 demo
    localForage——轻松实现 Web 离线存储
    迷你MVVM框架 avalonjs 1.2.6发布
    收起.NET程序的dll来
    从锅炉工到AI专家 ---- 系列教程
    DevExpress中实现GridControl的分页功能
    树莓派 ---- 个人总结
    树莓派安装内网穿透版花生壳服务
    winform 多线程中ShowDialog()模式窗口无效的解决办法
    局域网匿名访问共享文件
  • 原文地址:https://www.cnblogs.com/mq0036/p/15672211.html
Copyright © 2020-2023  润新知