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 ...
随机推荐
- 龙芯电脑上Electron应用开发
背景 最近在一台龙芯电脑(系统是中兴新支点,Linux)上开发electron应用. PS:龙芯是国产的cpu,采用是mips架构,类似x86.arm. 安装NodeJS 安装步骤请查看:https: ...
- js执行机制
js是单线程的,为什么可以执行异步操作呢? 这归结与浏览器(js的宿主环境)通过某种方式使得js具备了异步的属性. 区分进程和线程: 进程:正在运行中的应用程序.每个进程都自己独立的内存空间.例如:打 ...
- 一个神奇的HTML标签-----marquee
今天无意中发现了一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 语法:<marquee>...</marqu ...
- 一些实用的Django+HTML设置
一.关于引入变量 1.变量引入方法: {% block 块名称 %} <p>{{变量名}}<p> {% endblock %} 2.引入变量的值中标签是否转义: 不转义: {% ...
- postgres centos 创建数据库 创建用户
一个小的流程关于如何创建数据库和用户,用以加强印象,以及留档备份 一.创建账户 1.登录postgres账户 su postgres 2.进入psql 指令 psql 3.创建用户 create US ...
- JavaWeb包含哪些内容
JavaWeb JavaWeb课程内容涉及:HTML5课程.CSS3.JavaScript.MySQL使用.JDBC连接池.Servlet.JSP.AJAX.jQuery.Bootstrap. 第一部 ...
- vue-cli3 用natapp 配置时 出现Invalid Host header的解决方案
natapp 网址:https://natapp.cn/ 用户名:137 **** **** 密码:26**_X** natapp 配置: 出现如下错误:Invalid Host he ...
- Java 创建线程的3种方法及各自优势
1. 继承 Thread 类,然后调用 start 方法. class MyThread extends Thread { //重写run方法,线程运行后,跑的就是run方法 public void ...
- 搜索某个目录下所有jar包中的mapper目录下的xml文件
rm -rf /mapper/* find /data/app/app-*/lib ! -path "*xnpush*" ! -path "*portal*" ...
- OC-系统音效播放
一.介绍 AudioToolbox.framework是一套基于C语言的框架,使用它来播放音效其本质是将短音频注册到系统声音服务(System Sound Service).System Soun ...