原文:WPF 获取系统 DPI 的多种方法

WPF 获取系统 DPI 的多种方法

由于 WPF 的尺寸单位和系统的 DPI 相关,我们有时需要获取 DPI 值来进行一些界面布局的调整,本文汇总了一些 WPF 程序中获取系统 DPI 的方法。

首先,定义如下结构体来分别保存 X 方向 和 Y 方向的分量值,通常情况下两个值是一致的。

public struct Dpi
{
public double X { get; set; } public double Y { get; set; } public Dpi(double x, double y)
{
X = x;
Y = y;
}
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

CompositionTarget

public static Dpi GetDpiFromVisual(Visual visual)
{
var source = PresentationSource.FromVisual(visual); var dpiX = 96.0;
var dpiY = 96.0; if (source?.CompositionTarget != null)
{
dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11;
dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22;
} return new Dpi(dpiX, dpiY);
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Win32 API

private const int LOGPIXELSX = 88;
private const int LOGPIXELSY = 90; [DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int index); [DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd); [DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDc); public static Dpi GetDpiByWin32()
{
var hDc = GetDC(IntPtr.Zero); var dpiX = GetDeviceCaps(hDc, LOGPIXELSX);
var dpiY = GetDeviceCaps(hDc, LOGPIXELSY); ReleaseDC(IntPtr.Zero, hDc);
return new Dpi(dpiX, dpiY);
}
 

SystemParameters

public static Dpi GetDpiBySystemParameters()
{
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Static; var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", bindingFlags);
var dpiYProperty = typeof(SystemParameters).GetProperty("DpiY", bindingFlags); var dpiX = 96.0;
var dpiY = 96.0; if (dpiXProperty != null)
{
dpiX = (double)dpiXProperty.GetValue(null, null);
} if (dpiYProperty != null)
{
dpiY = (double)dpiYProperty.GetValue(null, null);
} return new Dpi(dpiX, dpiY);
}

Graphics
添加 System.Drawing 引用

public static Dpi GetDpiByGraphics()
{
double dpiX;
double dpiY; using (var graphics = Graphics.FromHwnd(IntPtr.Zero))
{
dpiX = graphics.DpiX;
dpiY = graphics.DpiY;
} return new Dpi(dpiX, dpiY);
}
 

ManagementClass
System.Management 引用

public static Dpi GetDpiByManagement()
{
var dpiX = 96.0;
var dpiY = 96.0; using (var mc = new ManagementClass("Win32_DesktopMonitor"))
{
using (var moc = mc.GetInstances())
{
// there may be many, to filter the ones you are interested in
foreach (var mo in moc)
{
dpiX = double.Parse(mo.Properties["PixelsPerXLogicalInch"].Value.ToString());
dpiY = double.Parse(mo.Properties["PixelsPerYLogicalInch"].Value.ToString());
}
}
} return new Dpi(dpiX, dpiY);
}
 

处于 跨平台、多屏幕、性能 等方面的综合考虑,推荐使用 CompositionTarget 方法。另外,监听系统 DPI 变化的方法:

SystemEvents.DisplaySettingsChanged - SystemEvents Class
WM_DPICHANGED message
参考资料
Best way to get DPI value in WPF
How can I get the DPI in WPF?
————————————————

版权声明:本文为CSDN博主「Iron_Ye」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Iron_Ye/article/details/83053393

WPF 获取系统 DPI 的多种方法的更多相关文章

  1. Android获取系统时间的多种方法

    Android中获取系统时间有多种方法,可分为Java中Calendar类获取,java.util.date类实现,还有android中Time实现. 现总结如下: 方法一: ? 1 2 3 4 5 ...

  2. PHP获取时间日期的多种方法

    分享下PHP获取时间日期的多种方法. <?php echo "今天:".date("Y-m-d")."<br>";     ...

  3. WPF 获取程序路径的一些方法,根据程序路径获取程序集信息

    一.WPF 获取程序路径的一些方法方式一 应用程序域 //获取基目录即当前工作目录 string str_1 = System.AppDomain.CurrentDomain.BaseDirector ...

  4. C# API 获取系统DPI缩放倍数跟分辨率大小

    原文:C# API 获取系统DPI缩放倍数跟分辨率大小 using System; using System.Drawing; using System.Runtime.InteropServices ...

  5. Shell获取字符串长度的多种方法总结

    摘自:https://www.jb51.net/article/121290.htm 前言 我们在日常工作中,对于求字符串操作在shell脚本中很常用,实现的方法有很多种,下面就来给大家归纳.汇总了求 ...

  6. 【Darwin学习笔记】之获取系统处理器数量的方法

    阅读Darwin源码的时候看到这个方法,感觉挺有用处,且考虑了多种平台下的实现方式,直接贴代码,以后说不定会用到~ 单一种平台下的实现方法可能很容易,但是把这些个系统都收集在一起,在一个函数中实现还是 ...

  7. 获取系统DPI、系统显示比例等

    using System; using System.Drawing; using System.Runtime.InteropServices; namespace XYDES { public c ...

  8. WPF获取程序版本号(Version)的方法

    1.第一种:通过System来获取 public static Version GetEdition() { return System.Reflection.Assembly.GetExecutin ...

  9. WPF实现系统禁音的方法

    方法1: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern ...

随机推荐

  1. js中关于constructor与prototype的理解

    1.①__proto__和constructor属性是对象所独有的:② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性. 2. ...

  2. YourSQLDba的共享路径备份遭遇重启问题

    如果YourSQLDba设置过共享路径备份(具体参考博客YourSQLDba设置共享路径备份),有时候服务器重启后,备份就会出错,具体错误信息类似如下所示: Date        2019/9/25 ...

  3. nvidia-smi 常用命令使用手册

    # 定时刷新 nvidia-smi 显示的结果 nvidia-smi -l 1  # 以 1 秒的频率进行刷新 nvidia-smi -lms 1 #以 1 毫秒的频率进行刷新 #保持更新,更多内容请 ...

  4. Linux禁用root用户

    在创建各种云主机的时候,云服务商给的都是root用户,这很方便,但是有某些时候会造成一些困扰,日后在服务器上启动各种服务后,仅仅拥有root权限的用户才能访问更改这些服务,这样会造成一些不必要的困扰, ...

  5. 附002.Minikube介绍及使用

    一 Minikube介绍 1.1 概述 Minikube是一种可以在本地轻松运行Kubernetes的工具.Minikube在笔记本电脑的VM中运行单节点Kubernetes集群,供希望尝试Kuber ...

  6. UTXO和Account模型一个都不能少

    UTXO对于非区块链从业人员来说可能比较陌生,UTXO的全称是Unspent Transaction Output,这中本聪在比特币中的一个天才设计.而Account模型就很常见,也很容易理解,你银行 ...

  7. sql server多表关联update

    一般都是写的单表update语句,很少写多表关联的update,但是事实上,在SQL Server中,update的多表连接更新和select的多表连接查询在使用的方法上其实并没有多大区别. 直接上一 ...

  8. Vue 从入门到进阶之路(十四)

    之前的文章我们对 vue 的基础用法已经有了很直观的认识,本章我们来看一下 vue 中的生命周期函数. 上图为 Vue官方为我们提供的完整的生命周期函数的流程图,下面的案例我们只是走了部分情况流程,但 ...

  9. java架构之-负载均衡-Ribbon 的使用

    一. 什么是负载均衡负载均衡就是分发请求流量到不同的服务器.负载均衡一般分为两种:1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 二. spring- - cloud- - ...

  10. CAD简易口诀,保你一天就记住!零基础也能轻松学!CAD制图宝典!

    如何才能快速的学习CAD制图呢?不仅仅需要多练习,CAD口诀也是不能错过的哦!实用干货这一个就够了快点收藏起来! 1.创建直线的快捷方式是L+空格 2.创建圆的快捷方式是C+空格 3.创建圆弧的快捷方 ...