原文: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. Mac Electron 应用的签名(signature)和公证(notarization)

    背景 在MacOS 10.15之前,应用如果没有签名,那么首次打开时就会弹出这种“恶意软件”的提示框. 这时只要应用签名了,就不会弹这个框. 但在MacOS 10.14.5之后,应用如果没有公证(简单 ...

  2. MySQL 社区版 安装小记

    根据刘铁猛老师的教程,自己折腾一下 1. 安装包准备 在Windows10 64bit上安装,故需要准备vc++ 2013和2015的Redistributable的包,搜索即有,无需细说. 示例数据 ...

  3. Mac Pro 2017款自带php与用brew重装PHP后的地址

    mac pro 2017款自带PHP与apache位置: [apache]apache配置文件 :/etc/apache2/httpd.confDocumentRoot : /Library/WebS ...

  4. c++ 拷贝构造函数(重点在内含指针的浅拷贝和深拷贝)

    今天同事问了一个关于拷贝构造函数的问题,类中包含指针的情况,今天就来说说c++的拷贝构造函数. c++的拷贝构造函数是构造函数的一种,是对类对象的初始化,拷贝构造函数只有一个参数就是本类的引用. 注意 ...

  5. C#&.Net干货分享- 构造BaiduLanguageHelper对接百度的语言翻译

    全部是封装的API源码... namespace Frame.Api{    /// <summary>    /// 百度多语言支持器    /// </summary>   ...

  6. SQL Server之批量清理数据库的死锁

    DECLARE killspid CURSOR  FOR (SELECT  CONVERT(VARCHAR(100), request_session_id)  FROM  sys.dm_tran_l ...

  7. 将CocoStudio产生的UI文件导入到项目

    配置: Xcode 6.0 + CocoStudio 1.6 + Cocos2d-x 3.4 添加资源 将导出的资源文件放到 Resource 文件夹下. 头文件 #include "coc ...

  8. 在浏览器地址栏输入www.baidu.com到打开百度首页这期间到底发生了什么?

    刚才无意间看到这么一个面试题,觉得有点意思,我想从五层网络模型的角度说说我的看法. 1.首先通过DNS域名系统向域名服务器发送域名解析请求来得到百度的IP地址39.156.69.79:2.系统通过AR ...

  9. atom 在Ubuntu 18.04 上安装及基本使用

    前记: Atom 是github专门为程序员推出的一个跨平台文本编辑器.具有简洁和直观的图形用户界面,并有很多有趣的特点:支持CSS,HTML,JavaScript等网页编程语言.它支持宏,自动完成分 ...

  10. C语言程序设计100例之(18):火柴棒等式

    例18   火柴棒等式 用n根火柴棍,可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棒拼出的整数(若该数非零,则最高位不能是0).用火柴棒拼数字0~9的拼法如图1所示. 图1  用 ...