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.

343 lines
9.9 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. // Old builds of Memphis had different indices for these metrics, and
  97. // some of the APIs and structs have changed since then, so validate that
  98. // the returned metrics are not totally messed up. (for example on an old
  99. // Memphis build, the new index for SM_CYVIRTUALSCREEN will fetch 0)
  100. //
  101. // If this is preventing you from using the shell on secondary monitors
  102. // under Memphis then upgrade to a new Memphis build that is in sync with
  103. // the current version of the multi-monitor APIs.
  104. //
  105. (GetSystemMetrics(SM_CXVIRTUALSCREEN) >= GetSystemMetrics(SM_CXSCREEN)) &&
  106. (GetSystemMetrics(SM_CYVIRTUALSCREEN) >= GetSystemMetrics(SM_CYSCREEN)) )
  107. {
  108. fInitDone = TRUE;
  109. return TRUE;
  110. }
  111. else
  112. {
  113. g_pfnGetSystemMetrics = NULL;
  114. g_pfnMonitorFromWindow = NULL;
  115. g_pfnMonitorFromRect = NULL;
  116. g_pfnMonitorFromPoint = NULL;
  117. g_pfnGetMonitorInfo = NULL;
  118. g_pfnEnumDisplayMonitors = NULL;
  119. fInitDone = TRUE;
  120. return FALSE;
  121. }
  122. }
  123. //-----------------------------------------------------------------------------
  124. //
  125. // fake implementations of Monitor APIs that work with the primary display
  126. // no special parameter validation is made since these run in client code
  127. //
  128. //-----------------------------------------------------------------------------
  129. int WINAPI
  130. xGetSystemMetrics(int nIndex)
  131. {
  132. if (InitMultipleMonitorStubs())
  133. return g_pfnGetSystemMetrics(nIndex);
  134. switch (nIndex)
  135. {
  136. case SM_CMONITORS:
  137. case SM_SAMEDISPLAYFORMAT:
  138. return 1;
  139. case SM_XVIRTUALSCREEN:
  140. case SM_YVIRTUALSCREEN:
  141. return 0;
  142. case SM_CXVIRTUALSCREEN:
  143. nIndex = SM_CXSCREEN;
  144. break;
  145. case SM_CYVIRTUALSCREEN:
  146. nIndex = SM_CYSCREEN;
  147. break;
  148. }
  149. return GetSystemMetrics(nIndex);
  150. }
  151. #define xPRIMARY_MONITOR ((HMONITOR)0x42)
  152. HMONITOR WINAPI
  153. xMonitorFromRect(LPCRECT lprcScreenCoords, UINT uFlags)
  154. {
  155. if (InitMultipleMonitorStubs())
  156. return g_pfnMonitorFromRect(lprcScreenCoords, uFlags);
  157. if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  158. ((lprcScreenCoords->right > 0) &&
  159. (lprcScreenCoords->bottom > 0) &&
  160. (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  161. (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  162. {
  163. return xPRIMARY_MONITOR;
  164. }
  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. HMONITOR WINAPI
  183. xMonitorFromWindow(HWND hWnd, UINT uFlags)
  184. {
  185. RECT rc;
  186. if (InitMultipleMonitorStubs())
  187. return g_pfnMonitorFromWindow(hWnd, uFlags);
  188. if (uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  189. return xPRIMARY_MONITOR;
  190. if (GetWindowRect(hWnd, &rc))
  191. return xMonitorFromRect(&rc, uFlags);
  192. return NULL;
  193. }
  194. BOOL WINAPI
  195. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  196. {
  197. RECT rcWork;
  198. if (InitMultipleMonitorStubs())
  199. return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  200. if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo &&
  201. (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  202. SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))
  203. {
  204. lpMonitorInfo->rcMonitor.left = 0;
  205. lpMonitorInfo->rcMonitor.top = 0;
  206. lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
  207. lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  208. lpMonitorInfo->rcWork = rcWork;
  209. lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  210. if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  211. lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  212. return TRUE;
  213. }
  214. return FALSE;
  215. }
  216. BOOL WINAPI
  217. xEnumDisplayMonitors(HDC hdcOptionalForPainting,
  218. LPCRECT lprcEnumMonitorsThatIntersect, MONITORENUMPROC lpfnEnumProc,
  219. LPARAM lData)
  220. {
  221. RECT rcCallback, rcLimit;
  222. if (InitMultipleMonitorStubs())
  223. return g_pfnEnumDisplayMonitors(hdcOptionalForPainting,
  224. lprcEnumMonitorsThatIntersect, lpfnEnumProc, lData);
  225. if (!lpfnEnumProc)
  226. return FALSE;
  227. rcLimit.left = 0;
  228. rcLimit.top = 0;
  229. rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
  230. rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  231. if (hdcOptionalForPainting)
  232. {
  233. RECT rcClip;
  234. HWND hWnd;
  235. if ((hWnd = WindowFromDC(hdcOptionalForPainting)) == NULL)
  236. return FALSE;
  237. switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  238. {
  239. default:
  240. MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);
  241. if (IntersectRect(&rcCallback, &rcClip, &rcLimit))
  242. break;
  243. //fall thru
  244. case NULLREGION:
  245. return TRUE;
  246. case ERROR:
  247. return FALSE;
  248. }
  249. rcLimit = rcCallback;
  250. }
  251. if (!lprcEnumMonitorsThatIntersect ||
  252. IntersectRect(&rcCallback, lprcEnumMonitorsThatIntersect, &rcLimit))
  253. {
  254. lpfnEnumProc(xPRIMARY_MONITOR, hdcOptionalForPainting, &rcCallback,
  255. lData);
  256. }
  257. return TRUE;
  258. }
  259. #undef xPRIMARY_MONITOR
  260. #undef COMPILE_MULTIMON_STUBS
  261. #else // COMPILE_MULTIMON_STUBS
  262. extern int WINAPI xGetSystemMetrics(int);
  263. extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);
  264. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);
  265. extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);
  266. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  267. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  268. #endif // COMPILE_MULTIMON_STUBS
  269. //
  270. // build defines that replace the regular APIs with our versions
  271. //
  272. #define GetSystemMetrics xGetSystemMetrics
  273. #define MonitorFromWindow xMonitorFromWindow
  274. #define MonitorFromRect xMonitorFromRect
  275. #define MonitorFromPoint xMonitorFromPoint
  276. #define GetMonitorInfo xGetMonitorInfo
  277. #define EnumDisplayMonitors xEnumDisplayMonitors
  278. #ifdef __cplusplus
  279. }
  280. #endif /* __cplusplus */
  281. #endif /* !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) */