public static class DPIGeter
{
/// <summary>
/// 获取DPI
/// </summary>
/// <param name="dpix"></param>
/// <param name="dpiy"></param>
public static void GetDPI(ref float dpix, ref float dpiy)
{
SetProcessDPIAware();//此处会忽视系统DWM虚拟化,不建议使用
IntPtr screenDC = GetDC(IntPtr.Zero);
dpix = GetDeviceCaps(screenDC, LOGPIXELSX);
dpiy = GetDeviceCaps(screenDC, LOGPIXELSY);
ReleaseDC(IntPtr.Zero, screenDC);
}
/// <summary>
/// 获取DPI缩放比例
/// </summary>
/// <param name="dpiscalex"></param>
/// <param name="dpiscaley"></param>
public static void GetDPIScale(ref float dpiscalex, ref float dpiscaley)
{
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
IntPtr hdc = GetDC(IntPtr.Zero);
int w = GetDeviceCaps(hdc, DESKTOPHORZRES);
int h = GetDeviceCaps(hdc, DESKTOPVERTRES);
ReleaseDC(IntPtr.Zero, hdc);
dpiscalex = (float)w / x;
dpiscaley = (float)h / y;
}
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr ptr); [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); [DllImport("gdi32.dll")]
public static extern IntPtr CreateDC(
string lpszDriver, // driver name
string lpszDevice, // device name
string lpszOutput, // not used; should be NULL
Int64 lpInitData // optional printer data
); [DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(
IntPtr hdc, // handle to DC
int nIndex // index of capability
); [DllImport("user32.dll")]
internal static extern bool SetProcessDPIAware(); [DllImport("user32")]
public static extern int GetSystemMetrics(
int nIndex
); [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect); public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
} const int DRIVERVERSION = ;
const int TECHNOLOGY = ;
const int HORZSIZE = ;
const int VERTSIZE = ;
const int HORZRES = ;
const int VERTRES = ;
const int BITSPIXEL = ;
const int PLANES = ;
const int NUMBRUSHES = ;
const int NUMPENS = ;
const int NUMMARKERS = ;
const int NUMFONTS = ;
const int NUMCOLORS = ;
const int PDEVICESIZE = ;
const int CURVECAPS = ;
const int LINECAPS = ;
const int POLYGONALCAPS = ;
const int TEXTCAPS = ;
const int CLIPCAPS = ;
const int RASTERCAPS = ;
const int ASPECTX = ;
const int ASPECTY = ;
const int ASPECTXY = ;
const int SHADEBLENDCAPS = ;
const int LOGPIXELSX = ;
const int LOGPIXELSY = ;
const int SIZEPALETTE = ;
const int NUMRESERVED = ;
const int COLORRES = ;
const int PHYSICALWIDTH = ;
const int PHYSICALHEIGHT = ;
const int PHYSICALOFFSETX = ;
const int PHYSICALOFFSETY = ;
const int SCALINGFACTORX = ;
const int SCALINGFACTORY = ;
const int VREFRESH = ;
const int DESKTOPVERTRES = ;
const int DESKTOPHORZRES = ;
const int BLTALIGNMENT = ;
const int SM_CXSCREEN = ;//'屏幕宽度
const int SM_CYSCREEN = ;//'屏幕高度
const int SM_CXVSCROLL = ;//'垂直滚动条的宽度
const int SM_CYHSCROLL = ;//'水平滚动条的宽度
const int SM_CYCAPTION = ;//'Height of windows caption 实际标题高度加上SM_CYBORDER
const int SM_CXBORDER = ;//'Width of no-sizable borders 无法测量的窗口框架宽度
const int SM_CYBORDER = ;// 'Height of non-sizable borders 无法测量的窗口框架高度
const int SM_CXDLGFRAME = ;// 'Width of dialog box borders
const int SM_CYDLGFRAME = ;//'Height of dialog box borders
const int SM_CYHTHUMB = ;//'Height of scroll box on horizontal scroll bar 水平滚动条上滑块的高度
const int SM_CXHTHUMB = ;//' Width of scroll box on horizontal scroll bar 水平滚动条上滑块的宽度
const int SM_CXICON = ;// 'Width of standard icon 图标宽度
const int SM_CYICON = ;//'Height of standard icon 图标高度
const int SM_CXCURSOR = ;//'Width of standard cursor 光标宽度
const int SM_CYCURSOR = ;//'Height of standard cursor 光标高度
const int SM_CYMENU = ;// 'Height of menu 以像素计算的单个菜单条的高度
const int SM_CXFULLSCREEN = ;// 'Width of client area of maximized window
const int SM_CYFULLSCREEN = ;// 'Height of client area of maximized window
const int SM_CYKANJIWINDOW = ;//'Height of Kanji window
const int SM_MOUSEPRESENT = ;//'True is a mouse is present 如果为TRUE或不为0的值则安装了鼠标,否则没有安装。
const int SM_CYVSCROLL = ;//'Height of arrow in vertical scroll bar
const int SM_CXHSCROLL = ;//'Width of arrow in vertical scroll bar
const int SM_DEBUG = ;//'True if deugging version of windows is running
const int SM_SWAPBUTTON = ;//'True if left and right buttons are swapped.
const int SM_CXMIN = ;// 'Minimum width of window
const int SM_CYMIN = ;//'Minimum height of window
const int SM_CXSIZE = ;//'Width of title bar bitmaps
const int SM_CYSIZE = ;//'height of title bar bitmaps
const int SM_CXMINTRACK = ;// 'Minimum tracking width of window
const int SM_CYMINTRACK = ;//'Minimum tracking height of window
const int SM_CXDOUBLECLK = ;// 'double click width
const int SM_CYDOUBLECLK = ;// 'double click height
const int SM_CXICONSPACING = ;//'width between desktop icons
const int SM_CYICONSPACING = ;//'height between desktop icons
const int SM_MENUDROPALIGNMENT = ;//'Zero if popup menus are aligned to the left of the memu bar item. True if it is aligned to the right.
const int SM_PENWINDOWS = ;// 'The handle of the pen windows DLL if loaded.
const int SM_DBCSENABLED = ;// 'True if double byte characteds are enabled
const int SM_CMOUSEBUTTONS = ;//'Number of mouse buttons.
const int SM_CMETRICS = ;// 'Number of system metrics
const int SM_CLEANBOOT = ;//'Windows 95 boot mode. 0 = normal, 1 = safe, 2 = safe with network
const int SM_CXMAXIMIZED = ;//'default width of win95 maximised window
const int SM_CXMAXTRACK = ;// 'maximum width when resizing win95 windows
const int SM_CXMENUCHECK = ;// 'width of menu checkmark bitmap
const int SM_CXMENUSIZE = ;//'width of button on menu bar
const int SM_CXMINIMIZED = ;// 'width of rectangle into which minimised windows must fit.
const int SM_CYMAXIMIZED = ;//'default height of win95 maximised window
const int SM_CYMAXTRACK = ;//'maximum width when resizing win95 windows
const int SM_CYMENUCHECK = ;//'height of menu checkmark bitmap
const int SM_CYMENUSIZE = ;//'height of button on menu bar
const int SM_CYMINIMIZED = ;// 'height of rectangle into which minimised windows must fit.
const int SM_CYSMCAPTION = ;// 'height of windows 95 small caption
const int SM_MIDEASTENABLED = ;// 'Hebrw and Arabic enabled for windows 95
const int SM_NETWORK = ;//'bit o is set if a network is present.
const int SM_SECURE = ;//'True if security is present on windows 95 system
const int SM_SLOWMACHINE = ;// 'true if machine is too slow to run win95.
}
附:
 SetProcessDPIAware和 IsProcessDPIAware, 通过调用SetProcessDPIAware, 我们告诉系统不要对我们的程序进行DWM虚拟化。
这里还有特殊情况也提一下: 我们在高DPI下通过窗口句柄取到的坐标信息是和目标程序是否支持DWM虚拟化相关联的, 我们对支持DWM虚拟化的程序窗口调用GetWindowRect, 取到的坐标也是经过DWM缩放后的坐标; 对禁用DWM虚拟化程序的窗口调用GetWindowRect, 取到的坐标则是没有经过缩放的原始坐标。

 最后我们再讨论下Win8.1 对高DPI的支持, WIn8.1对高DPi以3种方式支持 Process_DPI_Awareness : 
typedef enum _Process_DPI_Awareness {
Process_DPI_Unaware            = 0,
Process_System_DPI_Aware       = 1,
Process_Per_Monitor_DPI_Aware  = 2
} Process_DPI_Awareness;
下面我们依次讨论这3种方式:

第一种Unaware, 该种方式是告诉系统, 我的程序不支持DPI aware, 请通过DWM虚拟化帮我们实现。 该方式和上面Win7/Win8对高DPI的支持的实现基本一样,主要区别是它通过GetWindowRect取到的坐标都是经过DWM缩放后的, 无论对方窗口是不是支持DWM虚拟化。
 
第二种方式是System DPI aware, 该方式下告诉系统, 我的程序会在启动的显示器上自己支持DPI aware, 所以不需要对我进行DWM 虚拟化。 但是当我的程序被拖动到其他DPI不一样的显示器时, 请对我们先进行system DWM虚拟化缩放。
 
第三种方式是Per Monitor DPI aware, 该方式是告诉系统, 请永远不要对我进行DWM虚拟化,我会自己针对不同的Monitor的DPi缩放比率进行缩放。
 

【C#】获取电脑DPI的更多相关文章

  1. C#/VB.NET 获取电脑属性(硬盘ID、硬盘容量、Cpu序列号、MAC地址、系统类型)

    在开发过程中,经常需要获取电脑的一些属性,如获取硬盘ID/CPU序列号/MAC地址作为来加密字符串. 1.硬盘 在我查看网上一些文档时,发现很多人对硬盘序列号很模糊~ 什么叫硬盘序列号?指的是作为一个 ...

  2. 使用RXTX获取电脑串口

    RXTX是javacomm串口通信的一个扩展 RXTX开发所需文件的下载地址:http://rxtx.qbang.org/wiki/index.php/Download 解压之后可以看到支持各个平台的 ...

  3. C# -- 使用System.Environment获取电脑的相关属性

    使用System.Environment获取电脑的相关属性 1.使用System.Environment获取电脑的相关属性(入门案例) static void Main(string[] args) ...

  4. vue 项目使用 webpack 构建自动获取电脑ip地址

    1.开发 H5 时移动端,经常会使用真机进行调试本地环境.webpack 配置服务器好多脚手架写的都是固定的,而在团队开发中需要每人配置自己的本机 ip 进行开发,每次开启开发环境的都需要修改,并且还 ...

  5. java工具类,在Windows,Linux系统获取电脑的MAC地址、本地IP、电脑名

    package com.cloudssaas.util; import java.io.BufferedReader; import java.io.IOException; import java. ...

  6. QT 获取电脑时间

    使用环境: VS2010 & QT Designer5 #include <QDateTime>  //包含头文件 QDateTime local(QDateTime::curre ...

  7. java获取电脑部分信息

    获取mac地址与cpu序列号 参考博客:https://www.jb51.net/article/94793.htm 另一篇参考地址没记录下来 package util; import java.io ...

  8. C#获取电脑型号、系统版本、内存大小、硬盘大小、CPU信息

    摘要 有时需要获取电脑的相关信息.这时可以通过调用windows api的方式,进行获取. 方法 可以通过在powershell中 通过下面的命令进行查询,然后可以通过c#调用获取需要的信息. gwm ...

  9. Java获取电脑IP、MAC、各种版本

    Java代码获取电脑IP.MAC.各种版本 package com.rapoo.middle.action; import java.io.BufferedReader; import java.io ...

随机推荐

  1. Codeforces 6D Lizards and Basements 2 dfs+暴力

    题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<se ...

  2. telnet远程登录协议

    什么是Telnet? 对于Telnet的认识,不同的人持有不同的观点,可以把Telnet当成一种通信协议,但是对于入侵者而言,Telnet只是一种远程登录的工具.一旦入侵者与远程主机建立了Telnet ...

  3. cocos2dx 3.x 避免空sprite

    由于cocos2dx 3.x中autobatch的,如果场景中含有空sprite(并且还不处于visible==false状态)的话,则会打断流水线(因为空sprite的贴图与其它元素的贴图必定不在同 ...

  4. JavaScript:RegExp对象的使用(整理)

    1. RegExp是什么? 对象表示正则表达式,它是对字符串执行模式匹配的强大工具. 2. 如何创建RegExp? 2.1 直接量语法 /pattern/attributes 2.2 创建RegExp ...

  5. HTML5背景音乐的暂停与播放

    HTML代码:     <audio id="myaudio" loop="loop" preload="auto" autoplay ...

  6. 服务器上装filezilla server后,本地的ftp客户端连接不上去

    公司一台服务器,上面装了filezilla server后,按平常配置好了,但是在本地用FTP客户端不管怎么连接都连接不上,本地FTP客户端总提示连接失败,远程filezilla server的界面也 ...

  7. redis基础之python连接redis(五)

    前言 前面介绍了在数据库命令行直接操作redis,现在学习使用python的redis包来操作redis,本人安装的是redis==2.10.6: 系列文章 redis安装和配置 redis命令行操作 ...

  8. Lua整理——table库

    table属性 table库是有一些辅助函数构成的,这些函数将table作为数组来操作. 当中.有对列表中插入和删除元素的函数,有对数组元素进行排序的函数.还有对链接一个数组中全部字符串的函数. 0. ...

  9. 源码编绎的时候报错 tengine-2.1.0 error: the HTTP rewrite module requires the PCRE library.

    ./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the mo ...

  10. 递增和递减进度条CCProgressTimer

    关于scheduleUpdate看这篇即可 http://www.benmutou.com/blog/archives/56 接下来是示例代码: CCSize size = CCDirector::s ...