Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
9.0 KiB

  1. #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
  2. //=============================================================================
  3. //
  4. // MULTIMON
  5. // stub module that fakes multiple monitor apis on pre Memphis Win32 OSes
  6. //
  7. // By using this header your code will work unchanged on Win95,
  8. // you will get back default values from GetSystemMetrics() for new metrics
  9. // and the new APIs will act like only one display is present.
  10. //
  11. // exactly one source must include this with COMPILE_MULTIMON_STUBS defined
  12. //
  13. //=============================================================================
  14. #ifdef __cplusplus
  15. extern "C" { /* Assume C declarations for C++ */
  16. #endif /* __cplusplus */
  17. //
  18. // if we are building on Win95/NT4 headers we need to declare this stuff ourselves
  19. //
  20. #ifndef SM_CMONITORS
  21. #define SM_XVIRTUALSCREEN 76
  22. #define SM_YVIRTUALSCREEN 77
  23. #define SM_CXVIRTUALSCREEN 78
  24. #define SM_CYVIRTUALSCREEN 79
  25. #define SM_CMONITORS 80
  26. #define SM_SAMEDISPLAYFORMAT 81
  27. DECLARE_HANDLE(HMONITOR);
  28. #define MONITOR_DEFAULTTONULL 0x00000000
  29. #define MONITOR_DEFAULTTOPRIMARY 0x00000001
  30. #define MONITOR_DEFAULTTONEAREST 0x00000002
  31. #define MONITORINFOF_PRIMARY 0x00000001
  32. typedef struct tagMONITORINFO
  33. {
  34. DWORD cbSize;
  35. RECT rcMonitor;
  36. RECT rcWork;
  37. DWORD dwFlags;
  38. } MONITORINFO, *LPMONITORINFO;
  39. #define CCHDEVICENAME 32
  40. #ifdef __cplusplus
  41. typedef struct tagMONITORINFOEX : public tagMONITORINFO
  42. {
  43. TCHAR szDevice[CCHDEVICENAME];
  44. } MONITORINFOEX, *LPMONITORINFOEX;
  45. #else
  46. typedef struct
  47. {
  48. MONITORINFO;
  49. TCHAR szDevice[CCHDEVICENAME];
  50. } MONITORINFOEX, *LPMONITORINFOEX;
  51. #endif
  52. typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
  53. #endif // SM_CMONITORS
  54. #undef GetMonitorInfo
  55. #undef GetSystemMetrics
  56. #undef MonitorFromWindow
  57. #undef MonitorFromRect
  58. #undef MonitorFromPoint
  59. #undef EnumDisplayMonitors
  60. //
  61. // define this to compile the stubs
  62. // otherwise you get the declarations
  63. //
  64. #ifdef COMPILE_MULTIMON_STUBS
  65. //-----------------------------------------------------------------------------
  66. //
  67. // Implement the API stubs.
  68. //
  69. //-----------------------------------------------------------------------------
  70. int (WINAPI* g_pfnGetSystemMetrics)(int);
  71. HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, BOOL);
  72. HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, BOOL);
  73. HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, BOOL);
  74. BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO);
  75. BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  76. BOOL InitMultipleMonitorStubs(void)
  77. {
  78. HMODULE hUser32;
  79. static BOOL fInitDone;
  80. if (fInitDone)
  81. {
  82. return g_pfnGetMonitorInfo != NULL;
  83. }
  84. if ((hUser32 = GetModuleHandle(TEXT("USER32"))) &&
  85. (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) &&
  86. (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) &&
  87. (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) &&
  88. (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) &&
  89. (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) &&
  90. #ifdef UNICODE
  91. (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoW")) &&
  92. #else
  93. (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) )
  94. #endif
  95. {
  96. fInitDone = TRUE;
  97. return TRUE;
  98. }
  99. else
  100. {
  101. g_pfnGetSystemMetrics = NULL;
  102. g_pfnMonitorFromWindow = NULL;
  103. g_pfnMonitorFromRect = NULL;
  104. g_pfnMonitorFromPoint = NULL;
  105. g_pfnGetMonitorInfo = NULL;
  106. g_pfnEnumDisplayMonitors = NULL;
  107. fInitDone = TRUE;
  108. return FALSE;
  109. }
  110. }
  111. //-----------------------------------------------------------------------------
  112. //
  113. // fake implementations of Monitor APIs that work with the primary display
  114. // no special parameter validation is made since these run in client code
  115. //
  116. //-----------------------------------------------------------------------------
  117. int WINAPI
  118. xGetSystemMetrics(int nIndex)
  119. {
  120. if (InitMultipleMonitorStubs())
  121. return g_pfnGetSystemMetrics(nIndex);
  122. switch (nIndex)
  123. {
  124. case SM_CMONITORS:
  125. case SM_SAMEDISPLAYFORMAT:
  126. return 1;
  127. case SM_XVIRTUALSCREEN:
  128. case SM_YVIRTUALSCREEN:
  129. return 0;
  130. case SM_CXVIRTUALSCREEN:
  131. nIndex = SM_CXSCREEN;
  132. break;
  133. case SM_CYVIRTUALSCREEN:
  134. nIndex = SM_CYSCREEN;
  135. break;
  136. }
  137. return GetSystemMetrics(nIndex);
  138. }
  139. #define xPRIMARY_MONITOR ((HMONITOR)0x42)
  140. HMONITOR WINAPI
  141. xMonitorFromRect(LPCRECT lprcScreenCoords, UINT uFlags)
  142. {
  143. if (InitMultipleMonitorStubs())
  144. return g_pfnMonitorFromRect(lprcScreenCoords, uFlags);
  145. if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  146. ((lprcScreenCoords->right > 0) &&
  147. (lprcScreenCoords->bottom > 0) &&
  148. (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  149. (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  150. {
  151. return xPRIMARY_MONITOR;
  152. }
  153. return NULL;
  154. }
  155. HMONITOR WINAPI
  156. xMonitorFromWindow(HWND hWnd, UINT uFlags)
  157. {
  158. RECT rc;
  159. if (InitMultipleMonitorStubs())
  160. return g_pfnMonitorFromWindow(hWnd, uFlags);
  161. if (uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  162. return xPRIMARY_MONITOR;
  163. if (GetWindowRect(hWnd, &rc))
  164. return xMonitorFromRect(&rc, uFlags);
  165. return NULL;
  166. }
  167. HMONITOR WINAPI
  168. xMonitorFromPoint(POINT ptScreenCoords, UINT uFlags)
  169. {
  170. if (InitMultipleMonitorStubs())
  171. return g_pfnMonitorFromPoint(ptScreenCoords, uFlags);
  172. if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  173. ((ptScreenCoords.x >= 0) &&
  174. (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
  175. (ptScreenCoords.y >= 0) &&
  176. (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
  177. {
  178. return xPRIMARY_MONITOR;
  179. }
  180. return NULL;
  181. }
  182. BOOL WINAPI
  183. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  184. {
  185. RECT rcWork;
  186. if (InitMultipleMonitorStubs())
  187. return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  188. if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo &&
  189. (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  190. SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))
  191. {
  192. lpMonitorInfo->rcMonitor.left = 0;
  193. lpMonitorInfo->rcMonitor.top = 0;
  194. lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
  195. lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  196. lpMonitorInfo->rcWork = rcWork;
  197. lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  198. if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  199. lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  200. return TRUE;
  201. }
  202. return FALSE;
  203. }
  204. BOOL WINAPI
  205. xEnumDisplayMonitors(
  206. HDC hdc,
  207. LPCRECT lprcIntersect,
  208. MONITORENUMPROC lpfnEnumProc,
  209. LPARAM lData)
  210. {
  211. RECT rcCallback, rcLimit;
  212. if (InitMultipleMonitorStubs())
  213. return g_pfnEnumDisplayMonitors(hdc,
  214. lprcIntersect, lpfnEnumProc, lData);
  215. if (!lpfnEnumProc)
  216. return FALSE;
  217. rcLimit.left = 0;
  218. rcLimit.top = 0;
  219. rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
  220. rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  221. if (hdc)
  222. {
  223. RECT rcClip;
  224. HWND hWnd;
  225. if ((hWnd = WindowFromDC(hdc)) == NULL)
  226. return FALSE;
  227. switch (GetClipBox(hdc, &rcClip))
  228. {
  229. default:
  230. MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);
  231. if (IntersectRect(&rcCallback, &rcClip, &rcLimit))
  232. break;
  233. //fall thru
  234. case NULLREGION:
  235. return TRUE;
  236. case ERROR:
  237. return FALSE;
  238. }
  239. rcLimit = rcCallback;
  240. }
  241. if (!lprcIntersect ||
  242. IntersectRect(&rcCallback, lprcIntersect, &rcLimit))
  243. {
  244. lpfnEnumProc(xPRIMARY_MONITOR, hdc, &rcCallback,lData);
  245. }
  246. return TRUE;
  247. }
  248. #undef xPRIMARY_MONITOR
  249. #undef COMPILE_MULTIMON_STUBS
  250. #else // COMPILE_MULTIMON_STUBS
  251. extern int WINAPI xGetSystemMetrics(int);
  252. extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);
  253. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);
  254. extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);
  255. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  256. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  257. #endif // COMPILE_MULTIMON_STUBS
  258. //
  259. // build defines that replace the regular APIs with our versions
  260. //
  261. #define GetSystemMetrics xGetSystemMetrics
  262. #define MonitorFromWindow xMonitorFromWindow
  263. #define MonitorFromRect xMonitorFromRect
  264. #define MonitorFromPoint xMonitorFromPoint
  265. #define GetMonitorInfo xGetMonitorInfo
  266. #define EnumDisplayMonitors xEnumDisplayMonitors
  267. #ifdef __cplusplus
  268. }
  269. #endif /* __cplusplus */
  270. #endif /* !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) */