DPI.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include "StdAfx.h"
  2. #include "DPI.h"
  3. #include "VersionHelpers.h"
  4. namespace DuiLib
  5. {
  6. //96 DPI = 100% scaling
  7. //120 DPI = 125% scaling
  8. //144 DPI = 150% scaling
  9. //168 DPI = 175% scaling
  10. //192 DPI = 200% scaling
  11. typedef HRESULT (WINAPI *LPSetProcessDpiAwareness)(
  12. _In_ PROCESS_DPI_AWARENESS value
  13. );
  14. typedef HRESULT (WINAPI *LPGetProcessDpiAwareness)(
  15. _In_ HANDLE hprocess,
  16. _Out_ PROCESS_DPI_AWARENESS *value
  17. );
  18. typedef HRESULT (WINAPI *LPGetDpiForMonitor)(
  19. _In_ HMONITOR hmonitor,
  20. _In_ MONITOR_DPI_TYPE dpiType,
  21. _Out_ UINT *dpiX,
  22. _Out_ UINT *dpiY
  23. );
  24. CDPI::CDPI()
  25. {
  26. m_nScaleFactor = 0;
  27. m_nScaleFactorSDA = 0;
  28. m_Awareness = PROCESS_PER_MONITOR_DPI_AWARE;
  29. SetScale(96);
  30. }
  31. int CDPI::GetDPIOfMonitor(HMONITOR hMonitor)
  32. {
  33. UINT dpix = 96, dpiy = 96;
  34. if (IsWindows8Point1OrGreater()) {
  35. HRESULT hr = E_FAIL;
  36. HMODULE hModule =::LoadLibrary(_T("Shcore.dll"));
  37. if(hModule != NULL) {
  38. LPGetDpiForMonitor GetDpiForMonitor = (LPGetDpiForMonitor)GetProcAddress(hModule, "GetDpiForMonitor");
  39. if (GetDpiForMonitor != NULL && GetDpiForMonitor(hMonitor,MDT_EFFECTIVE_DPI, &dpix, &dpiy) != S_OK) {
  40. MessageBox(NULL, _T("GetDpiForMonitor failed"), _T("Notification"), MB_OK);
  41. return 96;
  42. }
  43. }
  44. }
  45. else {
  46. HDC screen = GetDC(0);
  47. dpix = GetDeviceCaps(screen, LOGPIXELSX);
  48. ReleaseDC(0, screen);
  49. }
  50. return dpix;
  51. }
  52. int CDPI::GetDPIOfMonitorNearestToPoint(POINT pt)
  53. {
  54. HMONITOR hMonitor;
  55. hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
  56. return GetDPIOfMonitor(hMonitor);
  57. }
  58. int CDPI::GetMainMonitorDPI()
  59. {
  60. POINT pt;
  61. // Get the DPI for the main monitor
  62. pt.x = 1;
  63. pt.y = 1;
  64. return GetDPIOfMonitorNearestToPoint(pt);
  65. }
  66. PROCESS_DPI_AWARENESS CDPI::GetDPIAwareness()
  67. {
  68. if (IsWindows8Point1OrGreater()) {
  69. HMODULE hModule =::LoadLibrary(_T("Shcore.dll"));
  70. if(hModule != NULL) {
  71. LPGetProcessDpiAwareness GetProcessDpiAwareness = (LPGetProcessDpiAwareness)GetProcAddress(hModule, "GetProcessDpiAwareness");
  72. if(GetProcessDpiAwareness != NULL) {
  73. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
  74. if(GetProcessDpiAwareness(hProcess, &m_Awareness) == S_OK) {
  75. }
  76. }
  77. }
  78. }
  79. return m_Awareness;
  80. }
  81. BOOL CDPI::SetDPIAwareness(PROCESS_DPI_AWARENESS Awareness)
  82. {
  83. BOOL bRet = FALSE;
  84. if (IsWindows8Point1OrGreater()) {
  85. HMODULE hModule =::LoadLibrary(_T("Shcore.dll"));
  86. if(hModule != NULL) {
  87. LPSetProcessDpiAwareness SetProcessDpiAwareness = (LPSetProcessDpiAwareness)GetProcAddress(hModule, "SetProcessDpiAwareness");
  88. if (SetProcessDpiAwareness != NULL && SetProcessDpiAwareness(Awareness) == S_OK) {
  89. m_Awareness = Awareness;
  90. bRet = TRUE;
  91. }
  92. }
  93. }
  94. else {
  95. m_Awareness = Awareness;
  96. }
  97. return bRet;
  98. }
  99. UINT DuiLib::CDPI::GetDPI()
  100. {
  101. if (m_Awareness == PROCESS_DPI_UNAWARE) {
  102. return 96;
  103. }
  104. if (m_Awareness == PROCESS_SYSTEM_DPI_AWARE) {
  105. return MulDiv(m_nScaleFactorSDA, 96, 100);
  106. }
  107. return MulDiv(m_nScaleFactor, 96, 100);
  108. }
  109. UINT CDPI::GetScale()
  110. {
  111. if (m_Awareness == PROCESS_DPI_UNAWARE) {
  112. return 100;
  113. }
  114. if (m_Awareness == PROCESS_SYSTEM_DPI_AWARE) {
  115. return m_nScaleFactorSDA;
  116. }
  117. return m_nScaleFactor;
  118. }
  119. void CDPI::SetScale(UINT uDPI)
  120. {
  121. m_nScaleFactor = MulDiv(uDPI, 100, 96);
  122. if (m_nScaleFactorSDA == 0) {
  123. m_nScaleFactorSDA = m_nScaleFactor;
  124. }
  125. }
  126. int CDPI::Scale(int iValue)
  127. {
  128. int iResult = iValue;
  129. if (m_Awareness == PROCESS_DPI_UNAWARE) {
  130. return iValue;
  131. }
  132. else if (m_Awareness == PROCESS_SYSTEM_DPI_AWARE) {
  133. iResult = MulDiv(iValue, m_nScaleFactorSDA, 100);
  134. }
  135. else{
  136. iResult = MulDiv(iValue, m_nScaleFactor, 100);
  137. }
  138. if(iValue > 0 && iResult == 0) iResult = 1;
  139. if(iValue < 0 && iResult == 0) iResult = -1;
  140. return iResult;
  141. }
  142. int CDPI::ScaleBack(int iValue) {
  143. if (m_Awareness == PROCESS_DPI_UNAWARE) {
  144. return iValue;
  145. }
  146. if (m_Awareness == PROCESS_SYSTEM_DPI_AWARE) {
  147. return MulDiv(iValue, 100, m_nScaleFactorSDA);
  148. }
  149. return MulDiv(iValue, 100, m_nScaleFactor);
  150. }
  151. RECT CDPI::Scale(RECT rcRect)
  152. {
  153. RECT rcScale = rcRect;
  154. int sw = Scale(rcRect.right - rcRect.left);
  155. int sh = Scale(rcRect.bottom - rcRect.top);
  156. rcScale.left = Scale(rcRect.left);
  157. rcScale.top = Scale(rcRect.top);
  158. rcScale.right = rcScale.left + sw;
  159. rcScale.bottom = rcScale.top + sh;
  160. return rcScale;
  161. }
  162. void CDPI::Scale(RECT *pRect)
  163. {
  164. int sw = Scale(pRect->right - pRect->left);
  165. int sh = Scale(pRect->bottom - pRect->top);
  166. pRect->left = Scale(pRect->left);
  167. pRect->top = Scale(pRect->top);
  168. pRect->right = pRect->left + sw;
  169. pRect->bottom = pRect->top + sh;
  170. }
  171. void CDPI::ScaleBack(RECT *pRect)
  172. {
  173. int sw = ScaleBack(pRect->right - pRect->left);
  174. int sh = ScaleBack(pRect->bottom - pRect->top);
  175. pRect->left = ScaleBack(pRect->left);
  176. pRect->top = ScaleBack(pRect->top);
  177. pRect->right = pRect->left + sw;
  178. pRect->bottom = pRect->top + sh;
  179. }
  180. void CDPI::Scale(POINT *pPoint)
  181. {
  182. pPoint->x = Scale(pPoint->x);
  183. pPoint->y = Scale(pPoint->y);
  184. }
  185. POINT CDPI::Scale(POINT ptPoint)
  186. {
  187. POINT ptScale = ptPoint;
  188. ptScale.x = Scale(ptPoint.x);
  189. ptScale.y = Scale(ptPoint.y);
  190. return ptScale;
  191. }
  192. void CDPI::Scale(SIZE *pSize)
  193. {
  194. pSize->cx = Scale(pSize->cx);
  195. pSize->cy = Scale(pSize->cy);
  196. }
  197. SIZE CDPI::Scale(SIZE szSize)
  198. {
  199. SIZE szScale = szSize;
  200. szScale.cx = Scale(szSize.cx);
  201. szScale.cy = Scale(szSize.cy);
  202. return szScale;
  203. }
  204. }