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. Linux内核(10) - 内核中的链表

    早上上班坐地铁要排队,到了公司楼下等电梯要排队,中午吃饭要排队,下班了追求一个女孩子也要排队,甚至在网上下载个什么门的短片也要排队,每次看见人群排成一条长龙时,才真正意识到自己是龙的传人.那么下面咱们 ...

  2. 做一个新产品需求,体验的分析文档?(例:喜马拉雅FM)

    2.1 战略层 2.11 产品定位: 一款产品覆盖面广,收听节目种类齐全,资源丰富的电台APP. 以PGC为主流,通过合作方式吸纳专业的电台人,节目人,行业名人分享内容. 融合UGC,满足人们在空闲时 ...

  3. win7 64 python2 xgboost安装

    综述: 首先,关于xgboost是啥,可以看这一篇:机器学习(四)--- 从gbdt到xgboost 安装Python3 环境下的xgboost 可以通过pip install , 在网址中下载对应版 ...

  4. python标准库介绍——13 types 模块详解

    == types 模块== ``types`` 模块包含了标准解释器定义的所有类型的类型对象, 如 [Example 1-86 #eg-1-86] 所示. 同一类型的所有对象共享一个类型对象. 你可以 ...

  5. Spring AOP声明式事务异常回滚(转)

    转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...

  6. ubuntu 16.04 apt-get 更新使用中科大镜像源

    1 备份系统配置 sudo cp /etc/apt/sources.list /etc/apt/source.list.bak 2 编辑配置 sudo vi /etc/apt/sources.list ...

  7. WCF使用net.tcp绑定时的注意事项

    IIS Express没有net.tcp绑定功能,本地测试的话只能使用本机的IIS进行承载,并且需要相应的配置(参见上一篇文章). 算了,直接举一个配置例子吧,懒得写了... <system.s ...

  8. 跟我一起学习VIM - vim插件合集

    2016-06-14 15:04 13333人阅读 评论(0) 收藏 举报 分类: Linux(104)  目录(?)[+]  前两天同事让我在小组内部分享一下VIM,于是我花了一点时间写了个简短的教 ...

  9. 模拟多级复选框效果的jquery代码

    jquery做了个多级复选框的效果,代码总共就20+行就over了. 我又想用js来做一个看看,才写了几个方法就写不动了,兼容性要考虑很多,而且代码量直线上升. 主要分享下jquery的这个效果的实现 ...

  10. Windows下打造Sublime Text + Tex Live环境

    一直在用Sublime Text + ctex集成环境编写Latex文档,最近发现ctex套件内嵌的MiKTeX包管理器功能太弱了,遂将目标转向了功能更加强大的Tex Live环境. 首先安装Tex ...