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.

476 lines
14 KiB

  1. //=============================================================================
  2. //
  3. // multimon.h -- Stub module that fakes multiple monitor apis on Win32 OSes
  4. // without them.
  5. //
  6. // By using this header your code will get back default values from
  7. // GetSystemMetrics() for new metrics, and the new multimonitor APIs
  8. // will act like only one display is present on a Win32 OS without
  9. // multimonitor APIs.
  10. //
  11. // Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.
  12. //
  13. // Copyright (c) Microsoft Corporation. All rights reserved.
  14. //
  15. //=============================================================================
  16. ;begin_both
  17. #ifdef __cplusplus
  18. extern "C" { // Assume C declarations for C++
  19. #endif // __cplusplus
  20. ;end_both
  21. //
  22. // If we are building with Win95/NT4 headers, we need to declare
  23. // the multimonitor-related metrics and APIs ourselves.
  24. //
  25. #ifndef SM_CMONITORS
  26. #define SM_XVIRTUALSCREEN 76
  27. #define SM_YVIRTUALSCREEN 77
  28. #define SM_CXVIRTUALSCREEN 78
  29. #define SM_CYVIRTUALSCREEN 79
  30. #define SM_CMONITORS 80
  31. #define SM_SAMEDISPLAYFORMAT 81
  32. // HMONITOR is already declared if WINVER >= 0x0500 in windef.h
  33. // This is for components built with an older version number.
  34. //
  35. #if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
  36. DECLARE_HANDLE(HMONITOR);
  37. #define HMONITOR_DECLARED
  38. #endif
  39. #define MONITOR_DEFAULTTONULL 0x00000000
  40. #define MONITOR_DEFAULTTOPRIMARY 0x00000001
  41. #define MONITOR_DEFAULTTONEAREST 0x00000002
  42. #define MONITORINFOF_PRIMARY 0x00000001
  43. typedef struct tagMONITORINFO
  44. {
  45. DWORD cbSize;
  46. RECT rcMonitor;
  47. RECT rcWork;
  48. DWORD dwFlags;
  49. } MONITORINFO, *LPMONITORINFO;
  50. #ifndef CCHDEVICENAME
  51. #define CCHDEVICENAME 32
  52. #endif
  53. #ifdef __cplusplus
  54. typedef struct tagMONITORINFOEXA : public tagMONITORINFO
  55. {
  56. CHAR szDevice[CCHDEVICENAME];
  57. } MONITORINFOEXA, *LPMONITORINFOEXA;
  58. typedef struct tagMONITORINFOEXW : public tagMONITORINFO
  59. {
  60. WCHAR szDevice[CCHDEVICENAME];
  61. } MONITORINFOEXW, *LPMONITORINFOEXW;
  62. #ifdef UNICODE
  63. typedef MONITORINFOEXW MONITORINFOEX;
  64. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  65. #else
  66. typedef MONITORINFOEXA MONITORINFOEX;
  67. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  68. #endif // UNICODE
  69. #else // ndef __cplusplus
  70. typedef struct tagMONITORINFOEXA
  71. {
  72. MONITORINFO;
  73. CHAR szDevice[CCHDEVICENAME];
  74. } MONITORINFOEXA, *LPMONITORINFOEXA;
  75. typedef struct tagMONITORINFOEXW
  76. {
  77. MONITORINFO;
  78. WCHAR szDevice[CCHDEVICENAME];
  79. } MONITORINFOEXW, *LPMONITORINFOEXW;
  80. #ifdef UNICODE
  81. typedef MONITORINFOEXW MONITORINFOEX;
  82. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  83. #else
  84. typedef MONITORINFOEXA MONITORINFOEX;
  85. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  86. #endif // UNICODE
  87. #endif
  88. typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
  89. #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
  90. typedef struct _DISPLAY_DEVICE% {
  91. DWORD cb;
  92. TCHAR% DeviceName[32];
  93. TCHAR% DeviceString[128];
  94. DWORD StateFlags;
  95. TCHAR% DeviceID[128];
  96. TCHAR% DeviceKey[128];
  97. } DISPLAY_DEVICE%, *PDISPLAY_DEVICE%, *LPDISPLAY_DEVICE%;
  98. #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
  99. #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
  100. #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
  101. #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
  102. #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
  103. #endif
  104. #endif // SM_CMONITORS
  105. #undef GetMonitorInfo
  106. #undef GetSystemMetrics
  107. #undef MonitorFromWindow
  108. #undef MonitorFromRect
  109. #undef MonitorFromPoint
  110. #undef EnumDisplayMonitors
  111. #undef EnumDisplayDevices
  112. //
  113. // Define COMPILE_MULTIMON_STUBS to compile the stubs;
  114. // otherwise, you get the declarations.
  115. //
  116. #ifdef COMPILE_MULTIMON_STUBS
  117. //-----------------------------------------------------------------------------
  118. //
  119. // Implement the API stubs.
  120. //
  121. //-----------------------------------------------------------------------------
  122. ;begin_both
  123. #ifndef MULTIMON_FNS_DEFINED
  124. int (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
  125. HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
  126. HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
  127. HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
  128. BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
  129. BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
  130. BOOL (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
  131. BOOL g_fMultiMonInitDone = FALSE;
  132. BOOL g_fMultimonPlatformNT = FALSE;
  133. #define MULTIMON_FNS_DEFINED ;Internal
  134. #endif
  135. ;end_both
  136. BOOL IsPlatformNT()
  137. {
  138. OSVERSIONINFOA osvi = {0};
  139. osvi.dwOSVersionInfoSize = sizeof(osvi);
  140. GetVersionExA((OSVERSIONINFOA*)&osvi);
  141. return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);
  142. }
  143. BOOL InitMultipleMonitorStubs(void)
  144. {
  145. HMODULE hUser32;
  146. if (g_fMultiMonInitDone)
  147. {
  148. return g_pfnGetMonitorInfo != NULL;
  149. }
  150. g_fMultimonPlatformNT = IsPlatformNT();
  151. hUser32 = GetModuleHandle(TEXT("USER32"));
  152. if (hUser32 &&
  153. (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
  154. (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
  155. (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
  156. (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
  157. (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
  158. #ifdef UNICODE
  159. (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
  160. (*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
  161. GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
  162. #else
  163. (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
  164. (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
  165. #endif
  166. ) {
  167. g_fMultiMonInitDone = TRUE;
  168. return TRUE;
  169. }
  170. else
  171. {
  172. g_pfnGetSystemMetrics = NULL;
  173. g_pfnMonitorFromWindow = NULL;
  174. g_pfnMonitorFromRect = NULL;
  175. g_pfnMonitorFromPoint = NULL;
  176. g_pfnGetMonitorInfo = NULL;
  177. g_pfnEnumDisplayMonitors = NULL;
  178. g_pfnEnumDisplayDevices = NULL;
  179. g_fMultiMonInitDone = TRUE;
  180. return FALSE;
  181. }
  182. }
  183. //-----------------------------------------------------------------------------
  184. //
  185. // fake implementations of Monitor APIs that work with the primary display
  186. // no special parameter validation is made since these run in client code
  187. //
  188. //-----------------------------------------------------------------------------
  189. int WINAPI
  190. xGetSystemMetrics(int nIndex)
  191. {
  192. if (InitMultipleMonitorStubs())
  193. return g_pfnGetSystemMetrics(nIndex);
  194. switch (nIndex)
  195. {
  196. case SM_CMONITORS:
  197. case SM_SAMEDISPLAYFORMAT:
  198. return 1;
  199. case SM_XVIRTUALSCREEN:
  200. case SM_YVIRTUALSCREEN:
  201. return 0;
  202. case SM_CXVIRTUALSCREEN:
  203. nIndex = SM_CXSCREEN;
  204. break;
  205. case SM_CYVIRTUALSCREEN:
  206. nIndex = SM_CYSCREEN;
  207. break;
  208. }
  209. return GetSystemMetrics(nIndex);
  210. }
  211. #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
  212. HMONITOR WINAPI
  213. xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
  214. {
  215. if (InitMultipleMonitorStubs())
  216. return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
  217. if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  218. ((ptScreenCoords.x >= 0) &&
  219. (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
  220. (ptScreenCoords.y >= 0) &&
  221. (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
  222. {
  223. return xPRIMARY_MONITOR;
  224. }
  225. return NULL;
  226. }
  227. HMONITOR WINAPI
  228. xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
  229. {
  230. if (InitMultipleMonitorStubs())
  231. return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
  232. if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  233. ((lprcScreenCoords->right > 0) &&
  234. (lprcScreenCoords->bottom > 0) &&
  235. (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  236. (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  237. {
  238. return xPRIMARY_MONITOR;
  239. }
  240. return NULL;
  241. }
  242. HMONITOR WINAPI
  243. xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
  244. {
  245. WINDOWPLACEMENT wp;
  246. if (InitMultipleMonitorStubs())
  247. return g_pfnMonitorFromWindow(hWnd, dwFlags);
  248. if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  249. return xPRIMARY_MONITOR;
  250. if (IsIconic(hWnd) ?
  251. GetWindowPlacement(hWnd, &wp) :
  252. GetWindowRect(hWnd, &wp.rcNormalPosition)) {
  253. return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
  254. }
  255. return NULL;
  256. }
  257. BOOL WINAPI
  258. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  259. {
  260. RECT rcWork;
  261. if (InitMultipleMonitorStubs())
  262. {
  263. BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  264. #ifdef UNICODE
  265. if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
  266. {
  267. MultiByteToWideChar(CP_ACP, 0,
  268. (LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
  269. ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  270. }
  271. #endif
  272. return f;
  273. }
  274. if ((hMonitor == xPRIMARY_MONITOR) &&
  275. lpMonitorInfo &&
  276. (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  277. SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
  278. {
  279. lpMonitorInfo->rcMonitor.left = 0;
  280. lpMonitorInfo->rcMonitor.top = 0;
  281. lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
  282. lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  283. lpMonitorInfo->rcWork = rcWork;
  284. lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  285. if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  286. {
  287. #ifdef UNICODE
  288. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  289. #else // UNICODE
  290. lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  291. #endif // UNICODE
  292. }
  293. return TRUE;
  294. }
  295. return FALSE;
  296. }
  297. BOOL WINAPI
  298. xEnumDisplayMonitors(
  299. HDC hdcOptionalForPainting,
  300. LPCRECT lprcEnumMonitorsThatIntersect,
  301. MONITORENUMPROC lpfnEnumProc,
  302. LPARAM dwData)
  303. {
  304. RECT rcLimit;
  305. if (InitMultipleMonitorStubs()) {
  306. return g_pfnEnumDisplayMonitors(
  307. hdcOptionalForPainting,
  308. lprcEnumMonitorsThatIntersect,
  309. lpfnEnumProc,
  310. dwData);
  311. }
  312. if (!lpfnEnumProc)
  313. return FALSE;
  314. rcLimit.left = 0;
  315. rcLimit.top = 0;
  316. rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
  317. rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  318. if (hdcOptionalForPainting)
  319. {
  320. RECT rcClip;
  321. POINT ptOrg;
  322. switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  323. {
  324. default:
  325. if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
  326. return FALSE;
  327. OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
  328. if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
  329. (!lprcEnumMonitorsThatIntersect ||
  330. IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
  331. break;
  332. }
  333. //fall thru
  334. case NULLREGION:
  335. return TRUE;
  336. case ERROR:
  337. return FALSE;
  338. }
  339. } else {
  340. if ( lprcEnumMonitorsThatIntersect &&
  341. !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
  342. return TRUE;
  343. }
  344. }
  345. return lpfnEnumProc(
  346. xPRIMARY_MONITOR,
  347. hdcOptionalForPainting,
  348. &rcLimit,
  349. dwData);
  350. }
  351. BOOL WINAPI
  352. xEnumDisplayDevices(
  353. PVOID Unused,
  354. DWORD iDevNum,
  355. PDISPLAY_DEVICE lpDisplayDevice,
  356. DWORD dwFlags)
  357. {
  358. if (InitMultipleMonitorStubs())
  359. return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);
  360. if (Unused != NULL)
  361. return FALSE;
  362. if (iDevNum != 0)
  363. return FALSE;
  364. if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
  365. return FALSE;
  366. #ifdef UNICODE
  367. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  368. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  369. #else // UNICODE
  370. lstrcpy((LPTSTR)lpDisplayDevice->DeviceName, TEXT("DISPLAY"));
  371. lstrcpy((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"));
  372. #endif // UNICODE
  373. lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
  374. return TRUE;
  375. }
  376. #undef xPRIMARY_MONITOR
  377. #undef COMPILE_MULTIMON_STUBS
  378. #else // COMPILE_MULTIMON_STUBS
  379. extern int WINAPI xGetSystemMetrics(int);
  380. extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
  381. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
  382. extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
  383. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  384. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  385. extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
  386. #endif // COMPILE_MULTIMON_STUBS
  387. //
  388. // build defines that replace the regular APIs with our versions
  389. //
  390. #define GetSystemMetrics xGetSystemMetrics
  391. #define MonitorFromWindow xMonitorFromWindow
  392. #define MonitorFromRect xMonitorFromRect
  393. #define MonitorFromPoint xMonitorFromPoint
  394. #define GetMonitorInfo xGetMonitorInfo
  395. #define EnumDisplayMonitors xEnumDisplayMonitors
  396. #define EnumDisplayDevices xEnumDisplayDevices
  397. ;begin_both
  398. #ifdef __cplusplus
  399. }
  400. #endif // __cplusplus
  401. ;end_both