原文: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. MSG结构

    MSG是Windows程序中的结构体,用于保存windows消息,定义: typedef struct tagMSG { HWND hwnd; //该消息所属的窗口句柄 UINT message; / ...

  2. mysql5.5下载安装教程

    下载地址:https://dev.mysql.com/downloads/mysql/ 这里选择的是5.5的版本: 步骤1: 步骤2: 步骤三: 步骤四: 步骤5: 步骤6: 步骤7: 步骤8: 步骤 ...

  3. Android 极光IM-高级篇-玩聊天app诞生

    距离上一次写 基础篇有了4个月,终于我写了一个 功能完善的即时通讯app,作为高级篇的担当出现.废话不多说,上图 app预览 ​​​​ ​​​​ ​​ 实现功能 1.用户的登录注册 2.单聊,能清空聊 ...

  4. 【Android】Android Studio NDK 开发

    Android Studio NDK 开发 记录在Android Studio中NDK简单开发的步骤 用到的Android Studio版本为3.5. 配置NDK 下载NDK 一般在SDK下已经有自带 ...

  5. C#后台架构师成长之路-Orm篇体系

    成为了高工,只是完成体系的熟练,这个时候就要学会啃一些框架了... 常用Orm底层框架的熟悉: 1.轻量泛型的DBHelper,一般高工都自己写的出来的 2.EF-基于Linq的,好好用 3.Keel ...

  6. 发布Cocos2d-x的PC端程序

    发布Cocos2d-x的PC端程序 一.创建一个Release的项目 1.利用根目录下的解决方案生成Release.win32文件夹 2.新建一个cocos2d项目(比如解决方案名称MySolutio ...

  7. springboot模板

    1.thymeleaf模板 2.Freemarker模板 Thymeleaf模板 首先导入依赖 <dependency> <groupId>org.springframewor ...

  8. 删除文件linux

    bool LxDeleteFile(const char* src){ int32_t iRe = remove(src); ) return true; else return false; }

  9. 对于文本生成类4种评价指标的的计算BLEU METEOR ROUGE CIDEr

    github下载链接:https://github.com/Maluuba/nlg-eval 将下载的文件放到工程目录,而后使用如下代码计算结果 具体的写作格式如下: from nlgeval imp ...

  10. (day67)组件、组件化、组件传参、JS补充(命名转换、for in 、数据转换)、css取消选中和模拟小手

    目录 一.初识组件 (一)概念 (二)特点 二.组件的分类 (一)根组件 (二)局部组件 (三)全局组件 二.数据组件化 三.组件的传参 (一)父传子 (二)子传父 四.JS补充 (一)与html命名 ...