1. public static class DPIGeter
  2. {
  3. /// <summary>
  4. /// 获取DPI
  5. /// </summary>
  6. /// <param name="dpix"></param>
  7. /// <param name="dpiy"></param>
  8. public static void GetDPI(ref float dpix, ref float dpiy)
  9. {
  10. SetProcessDPIAware();//此处会忽视系统DWM虚拟化,不建议使用
  11. IntPtr screenDC = GetDC(IntPtr.Zero);
  12. dpix = GetDeviceCaps(screenDC, LOGPIXELSX);
  13. dpiy = GetDeviceCaps(screenDC, LOGPIXELSY);
  14. ReleaseDC(IntPtr.Zero, screenDC);
  15. }
  16. /// <summary>
  17. /// 获取DPI缩放比例
  18. /// </summary>
  19. /// <param name="dpiscalex"></param>
  20. /// <param name="dpiscaley"></param>
  21. public static void GetDPIScale(ref float dpiscalex, ref float dpiscaley)
  22. {
  23. int x = GetSystemMetrics(SM_CXSCREEN);
  24. int y = GetSystemMetrics(SM_CYSCREEN);
  25. IntPtr hdc = GetDC(IntPtr.Zero);
  26. int w = GetDeviceCaps(hdc, DESKTOPHORZRES);
  27. int h = GetDeviceCaps(hdc, DESKTOPVERTRES);
  28. ReleaseDC(IntPtr.Zero, hdc);
  29. dpiscalex = (float)w / x;
  30. dpiscaley = (float)h / y;
  31. }
  32. [DllImport("user32.dll")]
  33. static extern IntPtr GetDC(IntPtr ptr);
  34.  
  35. [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
  36. public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
  37.  
  38. [DllImport("gdi32.dll")]
  39. public static extern IntPtr CreateDC(
  40. string lpszDriver, // driver name
  41. string lpszDevice, // device name
  42. string lpszOutput, // not used; should be NULL
  43. Int64 lpInitData // optional printer data
  44. );
  45.  
  46. [DllImport("gdi32.dll")]
  47. public static extern int GetDeviceCaps(
  48. IntPtr hdc, // handle to DC
  49. int nIndex // index of capability
  50. );
  51.  
  52. [DllImport("user32.dll")]
  53. internal static extern bool SetProcessDPIAware();
  54.  
  55. [DllImport("user32")]
  56. public static extern int GetSystemMetrics(
  57. int nIndex
  58. );
  59.  
  60. [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", CharSet = CharSet.Auto, SetLastError = true)]
  61. public static extern IntPtr GetDesktopWindow();
  62.  
  63. [DllImport("user32.dll")]
  64. public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);
  65.  
  66. public struct Rect
  67. {
  68. public int Left;
  69. public int Top;
  70. public int Right;
  71. public int Bottom;
  72. }
  73.  
  74. const int DRIVERVERSION = ;
  75. const int TECHNOLOGY = ;
  76. const int HORZSIZE = ;
  77. const int VERTSIZE = ;
  78. const int HORZRES = ;
  79. const int VERTRES = ;
  80. const int BITSPIXEL = ;
  81. const int PLANES = ;
  82. const int NUMBRUSHES = ;
  83. const int NUMPENS = ;
  84. const int NUMMARKERS = ;
  85. const int NUMFONTS = ;
  86. const int NUMCOLORS = ;
  87. const int PDEVICESIZE = ;
  88. const int CURVECAPS = ;
  89. const int LINECAPS = ;
  90. const int POLYGONALCAPS = ;
  91. const int TEXTCAPS = ;
  92. const int CLIPCAPS = ;
  93. const int RASTERCAPS = ;
  94. const int ASPECTX = ;
  95. const int ASPECTY = ;
  96. const int ASPECTXY = ;
  97. const int SHADEBLENDCAPS = ;
  98. const int LOGPIXELSX = ;
  99. const int LOGPIXELSY = ;
  100. const int SIZEPALETTE = ;
  101. const int NUMRESERVED = ;
  102. const int COLORRES = ;
  103. const int PHYSICALWIDTH = ;
  104. const int PHYSICALHEIGHT = ;
  105. const int PHYSICALOFFSETX = ;
  106. const int PHYSICALOFFSETY = ;
  107. const int SCALINGFACTORX = ;
  108. const int SCALINGFACTORY = ;
  109. const int VREFRESH = ;
  110. const int DESKTOPVERTRES = ;
  111. const int DESKTOPHORZRES = ;
  112. const int BLTALIGNMENT = ;
  113. const int SM_CXSCREEN = ;//'屏幕宽度
  114. const int SM_CYSCREEN = ;//'屏幕高度
  115. const int SM_CXVSCROLL = ;//'垂直滚动条的宽度
  116. const int SM_CYHSCROLL = ;//'水平滚动条的宽度
  117. const int SM_CYCAPTION = ;//'Height of windows caption 实际标题高度加上SM_CYBORDER
  118. const int SM_CXBORDER = ;//'Width of no-sizable borders 无法测量的窗口框架宽度
  119. const int SM_CYBORDER = ;// 'Height of non-sizable borders 无法测量的窗口框架高度
  120. const int SM_CXDLGFRAME = ;// 'Width of dialog box borders
  121. const int SM_CYDLGFRAME = ;//'Height of dialog box borders
  122. const int SM_CYHTHUMB = ;//'Height of scroll box on horizontal scroll bar 水平滚动条上滑块的高度
  123. const int SM_CXHTHUMB = ;//' Width of scroll box on horizontal scroll bar 水平滚动条上滑块的宽度
  124. const int SM_CXICON = ;// 'Width of standard icon 图标宽度
  125. const int SM_CYICON = ;//'Height of standard icon 图标高度
  126. const int SM_CXCURSOR = ;//'Width of standard cursor 光标宽度
  127. const int SM_CYCURSOR = ;//'Height of standard cursor 光标高度
  128. const int SM_CYMENU = ;// 'Height of menu 以像素计算的单个菜单条的高度
  129. const int SM_CXFULLSCREEN = ;// 'Width of client area of maximized window
  130. const int SM_CYFULLSCREEN = ;// 'Height of client area of maximized window
  131. const int SM_CYKANJIWINDOW = ;//'Height of Kanji window
  132. const int SM_MOUSEPRESENT = ;//'True is a mouse is present 如果为TRUE或不为0的值则安装了鼠标,否则没有安装。
  133. const int SM_CYVSCROLL = ;//'Height of arrow in vertical scroll bar
  134. const int SM_CXHSCROLL = ;//'Width of arrow in vertical scroll bar
  135. const int SM_DEBUG = ;//'True if deugging version of windows is running
  136. const int SM_SWAPBUTTON = ;//'True if left and right buttons are swapped.
  137. const int SM_CXMIN = ;// 'Minimum width of window
  138. const int SM_CYMIN = ;//'Minimum height of window
  139. const int SM_CXSIZE = ;//'Width of title bar bitmaps
  140. const int SM_CYSIZE = ;//'height of title bar bitmaps
  141. const int SM_CXMINTRACK = ;// 'Minimum tracking width of window
  142. const int SM_CYMINTRACK = ;//'Minimum tracking height of window
  143. const int SM_CXDOUBLECLK = ;// 'double click width
  144. const int SM_CYDOUBLECLK = ;// 'double click height
  145. const int SM_CXICONSPACING = ;//'width between desktop icons
  146. const int SM_CYICONSPACING = ;//'height between desktop icons
  147. 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.
  148. const int SM_PENWINDOWS = ;// 'The handle of the pen windows DLL if loaded.
  149. const int SM_DBCSENABLED = ;// 'True if double byte characteds are enabled
  150. const int SM_CMOUSEBUTTONS = ;//'Number of mouse buttons.
  151. const int SM_CMETRICS = ;// 'Number of system metrics
  152. const int SM_CLEANBOOT = ;//'Windows 95 boot mode. 0 = normal, 1 = safe, 2 = safe with network
  153. const int SM_CXMAXIMIZED = ;//'default width of win95 maximised window
  154. const int SM_CXMAXTRACK = ;// 'maximum width when resizing win95 windows
  155. const int SM_CXMENUCHECK = ;// 'width of menu checkmark bitmap
  156. const int SM_CXMENUSIZE = ;//'width of button on menu bar
  157. const int SM_CXMINIMIZED = ;// 'width of rectangle into which minimised windows must fit.
  158. const int SM_CYMAXIMIZED = ;//'default height of win95 maximised window
  159. const int SM_CYMAXTRACK = ;//'maximum width when resizing win95 windows
  160. const int SM_CYMENUCHECK = ;//'height of menu checkmark bitmap
  161. const int SM_CYMENUSIZE = ;//'height of button on menu bar
  162. const int SM_CYMINIMIZED = ;// 'height of rectangle into which minimised windows must fit.
  163. const int SM_CYSMCAPTION = ;// 'height of windows 95 small caption
  164. const int SM_MIDEASTENABLED = ;// 'Hebrw and Arabic enabled for windows 95
  165. const int SM_NETWORK = ;//'bit o is set if a network is present.
  166. const int SM_SECURE = ;//'True if security is present on windows 95 system
  167. const int SM_SLOWMACHINE = ;// 'true if machine is too slow to run win95.
  168. }
附:
 SetProcessDPIAware和 IsProcessDPIAware, 通过调用SetProcessDPIAware, 我们告诉系统不要对我们的程序进行DWM虚拟化。
这里还有特殊情况也提一下: 我们在高DPI下通过窗口句柄取到的坐标信息是和目标程序是否支持DWM虚拟化相关联的, 我们对支持DWM虚拟化的程序窗口调用GetWindowRect, 取到的坐标也是经过DWM缩放后的坐标; 对禁用DWM虚拟化程序的窗口调用GetWindowRect, 取到的坐标则是没有经过缩放的原始坐标。

 最后我们再讨论下Win8.1 对高DPI的支持, WIn8.1对高DPi以3种方式支持 Process_DPI_Awareness : 
  1. typedef enum _Process_DPI_Awareness {
  2. Process_DPI_Unaware            = 0,
  3. Process_System_DPI_Aware       = 1,
  4. Process_Per_Monitor_DPI_Aware  = 2
  5. } 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. jdbc与odbc的差别,感悟,学习。。。

    什么是JDBC? JDBC, 全称为Java DataBase Connectivity standard, 它是一个面向对象的应用程序接口(API), 通过它可訪问各类关系数据库.JDBC也是jav ...

  2. Cocos2d-x游戏移植到WP8之路 -- c++和c#交互

    Cocos2d-x是眼下最流行的手机游戏引擎之中的一个,开源.轻量.多平台等的诸多特性使得它被非常多国内外手游开发人员所喜爱. 利用Cocos2d-x来开发Windows Phone 8的游戏相同也是 ...

  3. python中如果函数后面有多于一个括号是怎么回事?

    一般而言,调用一个函数是加一个括号.如果看见括号后还有一个括号,说明第一个函数返回了一个函数,如果后面还有括号,说明前面那个也返回了一个函数.以此类推. 比如fun()() def fun(): pr ...

  4. django1.8forms读书笔记

    一.HttpRequest对象的一些属性或方法 request.path,The full path, not including the domain but including the leadi ...

  5. 利用PHPExcel实现数据保存到excel文件

    include(dirname(__FILE__) .'/phpexcel-1.7.7/Classes/PHPExcel.php'); include(dirname(__FILE__) .'/php ...

  6. cocos2dx 3.x draw debug

    有时候需要用ccDrawXXX绘制debug线框来调试图形程序. 在cocos2dx 2.x中,由于是立即模式,所以如果在draw函数中用ccDrawXXX画线框,要用节点的局部坐标. 在cocos2 ...

  7. springcloud Ribbon自定义负载均衡插件

    现在我们通过插件的方式添加新的一种策略. package com.zhuyang.config; import org.springframework.beans.factory.annotation ...

  8. asp.net MVC学习的一些总结

    起初认为视图,控制器,模型它们是完全没有耦合的,真正用了一段时间MVC发现错了. 但通过抽象让他们完全没有耦合,也不是不可能. 1.奇怪的连接地址 用MVC之前,一直认为页面必然访问某个文件.用了MV ...

  9. paip.中文 分词 ---paoding 3.1 的使用

    paip.中文 分词 ---paoding 3.1 的使用 paoding 3.1 下载: 1 设置字典路径 1 测试代码 1 作者Attilax  艾龙,  EMAIL:1466519819@qq. ...

  10. Ubantu MySQL数据库操作

    用户管理: 1.新建用户: >CREATE USER name IDENTIFIED BY 'ssapdrow'; 2.更改密码: >SET PASSWORD FOR name=PASSW ...