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 的多种方法的更多相关文章
- Android获取系统时间的多种方法
Android中获取系统时间有多种方法,可分为Java中Calendar类获取,java.util.date类实现,还有android中Time实现. 现总结如下: 方法一: ? 1 2 3 4 5 ...
- PHP获取时间日期的多种方法
分享下PHP获取时间日期的多种方法. <?php echo "今天:".date("Y-m-d")."<br>"; ...
- WPF 获取程序路径的一些方法,根据程序路径获取程序集信息
一.WPF 获取程序路径的一些方法方式一 应用程序域 //获取基目录即当前工作目录 string str_1 = System.AppDomain.CurrentDomain.BaseDirector ...
- C# API 获取系统DPI缩放倍数跟分辨率大小
原文:C# API 获取系统DPI缩放倍数跟分辨率大小 using System; using System.Drawing; using System.Runtime.InteropServices ...
- Shell获取字符串长度的多种方法总结
摘自:https://www.jb51.net/article/121290.htm 前言 我们在日常工作中,对于求字符串操作在shell脚本中很常用,实现的方法有很多种,下面就来给大家归纳.汇总了求 ...
- 【Darwin学习笔记】之获取系统处理器数量的方法
阅读Darwin源码的时候看到这个方法,感觉挺有用处,且考虑了多种平台下的实现方式,直接贴代码,以后说不定会用到~ 单一种平台下的实现方法可能很容易,但是把这些个系统都收集在一起,在一个函数中实现还是 ...
- 获取系统DPI、系统显示比例等
using System; using System.Drawing; using System.Runtime.InteropServices; namespace XYDES { public c ...
- WPF获取程序版本号(Version)的方法
1.第一种:通过System来获取 public static Version GetEdition() { return System.Reflection.Assembly.GetExecutin ...
- WPF实现系统禁音的方法
方法1: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern ...
随机推荐
- Mac Electron 应用的签名(signature)和公证(notarization)
背景 在MacOS 10.15之前,应用如果没有签名,那么首次打开时就会弹出这种“恶意软件”的提示框. 这时只要应用签名了,就不会弹这个框. 但在MacOS 10.14.5之后,应用如果没有公证(简单 ...
- MySQL 社区版 安装小记
根据刘铁猛老师的教程,自己折腾一下 1. 安装包准备 在Windows10 64bit上安装,故需要准备vc++ 2013和2015的Redistributable的包,搜索即有,无需细说. 示例数据 ...
- Mac Pro 2017款自带php与用brew重装PHP后的地址
mac pro 2017款自带PHP与apache位置: [apache]apache配置文件 :/etc/apache2/httpd.confDocumentRoot : /Library/WebS ...
- c++ 拷贝构造函数(重点在内含指针的浅拷贝和深拷贝)
今天同事问了一个关于拷贝构造函数的问题,类中包含指针的情况,今天就来说说c++的拷贝构造函数. c++的拷贝构造函数是构造函数的一种,是对类对象的初始化,拷贝构造函数只有一个参数就是本类的引用. 注意 ...
- C#&.Net干货分享- 构造BaiduLanguageHelper对接百度的语言翻译
全部是封装的API源码... namespace Frame.Api{ /// <summary> /// 百度多语言支持器 /// </summary> ...
- SQL Server之批量清理数据库的死锁
DECLARE killspid CURSOR FOR (SELECT CONVERT(VARCHAR(100), request_session_id) FROM sys.dm_tran_l ...
- 将CocoStudio产生的UI文件导入到项目
配置: Xcode 6.0 + CocoStudio 1.6 + Cocos2d-x 3.4 添加资源 将导出的资源文件放到 Resource 文件夹下. 头文件 #include "coc ...
- 在浏览器地址栏输入www.baidu.com到打开百度首页这期间到底发生了什么?
刚才无意间看到这么一个面试题,觉得有点意思,我想从五层网络模型的角度说说我的看法. 1.首先通过DNS域名系统向域名服务器发送域名解析请求来得到百度的IP地址39.156.69.79:2.系统通过AR ...
- atom 在Ubuntu 18.04 上安装及基本使用
前记: Atom 是github专门为程序员推出的一个跨平台文本编辑器.具有简洁和直观的图形用户界面,并有很多有趣的特点:支持CSS,HTML,JavaScript等网页编程语言.它支持宏,自动完成分 ...
- C语言程序设计100例之(18):火柴棒等式
例18 火柴棒等式 用n根火柴棍,可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棒拼出的整数(若该数非零,则最高位不能是0).用火柴棒拼数字0~9的拼法如图1所示. 图1 用 ...