home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / include / multimon.h < prev    next >
C/C++ Source or Header  |  2000-09-21  |  15KB  |  485 lines

  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) 1985-1998, Microsoft Corporation
  14. //
  15. //=============================================================================
  16.  
  17. #ifdef __cplusplus
  18. extern "C" {            // Assume C declarations for C++
  19. #endif // __cplusplus
  20.  
  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.  
  27. #define SM_XVIRTUALSCREEN       76
  28. #define SM_YVIRTUALSCREEN       77
  29. #define SM_CXVIRTUALSCREEN      78
  30. #define SM_CYVIRTUALSCREEN      79
  31. #define SM_CMONITORS            80
  32. #define SM_SAMEDISPLAYFORMAT    81
  33.  
  34. // HMONITOR is already declared if WINVER >= 0x0500 in windef.h
  35. // This is for components built with an older version number.
  36. //
  37. #if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
  38. DECLARE_HANDLE(HMONITOR);
  39. #define HMONITOR_DECLARED
  40. #endif
  41.  
  42. #define MONITOR_DEFAULTTONULL       0x00000000
  43. #define MONITOR_DEFAULTTOPRIMARY    0x00000001
  44. #define MONITOR_DEFAULTTONEAREST    0x00000002
  45.  
  46. #define MONITORINFOF_PRIMARY        0x00000001
  47.  
  48. typedef struct tagMONITORINFO
  49. {
  50.     DWORD   cbSize;
  51.     RECT    rcMonitor;
  52.     RECT    rcWork;
  53.     DWORD   dwFlags;
  54. } MONITORINFO, *LPMONITORINFO;
  55.  
  56. #ifndef CCHDEVICENAME
  57. #define CCHDEVICENAME 32
  58. #endif
  59.  
  60. #ifdef __cplusplus
  61. typedef struct tagMONITORINFOEXA : public tagMONITORINFO
  62. {
  63.     CHAR        szDevice[CCHDEVICENAME];
  64. } MONITORINFOEXA, *LPMONITORINFOEXA;
  65. typedef struct tagMONITORINFOEXW : public tagMONITORINFO
  66. {
  67.     WCHAR       szDevice[CCHDEVICENAME];
  68. } MONITORINFOEXW, *LPMONITORINFOEXW;
  69. #ifdef UNICODE
  70. typedef MONITORINFOEXW MONITORINFOEX;
  71. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  72. #else
  73. typedef MONITORINFOEXA MONITORINFOEX;
  74. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  75. #endif // UNICODE
  76. #else // ndef __cplusplus
  77. typedef struct tagMONITORINFOEXA
  78. {
  79.     MONITORINFO;
  80.     CHAR        szDevice[CCHDEVICENAME];
  81. } MONITORINFOEXA, *LPMONITORINFOEXA;
  82. typedef struct tagMONITORINFOEXW
  83. {
  84.     MONITORINFO;
  85.     WCHAR       szDevice[CCHDEVICENAME];
  86. } MONITORINFOEXW, *LPMONITORINFOEXW;
  87. #ifdef UNICODE
  88. typedef MONITORINFOEXW MONITORINFOEX;
  89. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  90. #else
  91. typedef MONITORINFOEXA MONITORINFOEX;
  92. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  93. #endif // UNICODE
  94. #endif
  95.  
  96. typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
  97.  
  98. #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
  99. typedef struct _DISPLAY_DEVICEA {
  100.     DWORD  cb;
  101.     CHAR   DeviceName[32];
  102.     CHAR   DeviceString[128];
  103.     DWORD  StateFlags;
  104.     CHAR   DeviceID[128];
  105.     CHAR   DeviceKey[128];
  106. } DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
  107. typedef struct _DISPLAY_DEVICEW {
  108.     DWORD  cb;
  109.     WCHAR  DeviceName[32];
  110.     WCHAR  DeviceString[128];
  111.     DWORD  StateFlags;
  112.     WCHAR  DeviceID[128];
  113.     WCHAR  DeviceKey[128];
  114. } DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
  115. #ifdef UNICODE
  116. typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
  117. typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
  118. typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
  119. #else
  120. typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
  121. typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
  122. typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
  123. #endif // UNICODE
  124.  
  125. #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
  126. #define DISPLAY_DEVICE_MULTI_DRIVER        0x00000002
  127. #define DISPLAY_DEVICE_PRIMARY_DEVICE      0x00000004
  128. #define DISPLAY_DEVICE_MIRRORING_DRIVER    0x00000008
  129. #define DISPLAY_DEVICE_VGA_COMPATIBLE      0x00000010
  130. #endif
  131.  
  132. #endif  // SM_CMONITORS
  133.  
  134. #undef GetMonitorInfo
  135. #undef GetSystemMetrics
  136. #undef MonitorFromWindow
  137. #undef MonitorFromRect
  138. #undef MonitorFromPoint
  139. #undef EnumDisplayMonitors
  140. #undef EnumDisplayDevices
  141.  
  142. //
  143. // Define COMPILE_MULTIMON_STUBS to compile the stubs;
  144. // otherwise, you get the declarations.
  145. //
  146. #ifdef COMPILE_MULTIMON_STUBS
  147.  
  148. //-----------------------------------------------------------------------------
  149. //
  150. // Implement the API stubs.
  151. //
  152. //-----------------------------------------------------------------------------
  153.  
  154. #ifndef MULTIMON_FNS_DEFINED
  155.  
  156. int      (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
  157. HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
  158. HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
  159. HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
  160. BOOL     (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
  161. BOOL     (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
  162. BOOL     (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
  163. BOOL     g_fMultiMonInitDone = FALSE;
  164. BOOL     g_fMultimonPlatformNT = FALSE;
  165.  
  166. #endif
  167.  
  168. BOOL IsPlatformNT()
  169.     OSVERSIONINFOA osvi = {0};
  170.     osvi.dwOSVersionInfoSize = sizeof(osvi);
  171.     GetVersionExA((OSVERSIONINFOA*)&osvi);
  172.     return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);    
  173. }
  174.  
  175. BOOL InitMultipleMonitorStubs(void)
  176. {
  177.     HMODULE hUser32;
  178.     if (g_fMultiMonInitDone)
  179.     {
  180.         return g_pfnGetMonitorInfo != NULL;
  181.     }
  182.  
  183.     g_fMultimonPlatformNT = IsPlatformNT();
  184.     hUser32 = GetModuleHandle(TEXT("USER32"));
  185.     if (hUser32 &&
  186.         (*(FARPROC*)&g_pfnGetSystemMetrics    = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
  187.         (*(FARPROC*)&g_pfnMonitorFromWindow   = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
  188.         (*(FARPROC*)&g_pfnMonitorFromRect     = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
  189.         (*(FARPROC*)&g_pfnMonitorFromPoint    = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
  190.         (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
  191. #ifdef UNICODE
  192.         (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
  193.         (*(FARPROC*)&g_pfnGetMonitorInfo      = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") : 
  194.                                                 GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
  195. #else
  196.         (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
  197.         (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
  198. #endif
  199.     ) {
  200.         g_fMultiMonInitDone = TRUE;
  201.         return TRUE;
  202.     }
  203.     else
  204.     {
  205.         g_pfnGetSystemMetrics    = NULL;
  206.         g_pfnMonitorFromWindow   = NULL;
  207.         g_pfnMonitorFromRect     = NULL;
  208.         g_pfnMonitorFromPoint    = NULL;
  209.         g_pfnGetMonitorInfo      = NULL;
  210.         g_pfnEnumDisplayMonitors = NULL;
  211.         g_pfnEnumDisplayDevices  = NULL;
  212.  
  213.         g_fMultiMonInitDone = TRUE;
  214.         return FALSE;
  215.     }
  216. }
  217.  
  218. //-----------------------------------------------------------------------------
  219. //
  220. // fake implementations of Monitor APIs that work with the primary display
  221. // no special parameter validation is made since these run in client code
  222. //
  223. //-----------------------------------------------------------------------------
  224.  
  225. int WINAPI
  226. xGetSystemMetrics(int nIndex)
  227. {
  228.     if (InitMultipleMonitorStubs())
  229.         return g_pfnGetSystemMetrics(nIndex);
  230.  
  231.     switch (nIndex)
  232.     {
  233.     case SM_CMONITORS:
  234.     case SM_SAMEDISPLAYFORMAT:
  235.         return 1;
  236.  
  237.     case SM_XVIRTUALSCREEN:
  238.     case SM_YVIRTUALSCREEN:
  239.         return 0;
  240.  
  241.     case SM_CXVIRTUALSCREEN:
  242.         nIndex = SM_CXSCREEN;
  243.         break;
  244.  
  245.     case SM_CYVIRTUALSCREEN:
  246.         nIndex = SM_CYSCREEN;
  247.         break;
  248.     }
  249.  
  250.     return GetSystemMetrics(nIndex);
  251. }
  252.  
  253. #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
  254.  
  255. HMONITOR WINAPI
  256. xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
  257. {
  258.     if (InitMultipleMonitorStubs())
  259.         return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
  260.  
  261.     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  262.         ((ptScreenCoords.x >= 0) &&
  263.         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
  264.         (ptScreenCoords.y >= 0) &&
  265.         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
  266.     {
  267.         return xPRIMARY_MONITOR;
  268.     }
  269.  
  270.     return NULL;
  271. }
  272.  
  273. HMONITOR WINAPI
  274. xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
  275. {
  276.     if (InitMultipleMonitorStubs())
  277.         return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
  278.  
  279.     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  280.         ((lprcScreenCoords->right > 0) &&
  281.         (lprcScreenCoords->bottom > 0) &&
  282.         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  283.         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  284.     {
  285.         return xPRIMARY_MONITOR;
  286.     }
  287.  
  288.     return NULL;
  289. }
  290.  
  291. HMONITOR WINAPI
  292. xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
  293. {
  294.     WINDOWPLACEMENT wp;
  295.  
  296.     if (InitMultipleMonitorStubs())
  297.         return g_pfnMonitorFromWindow(hWnd, dwFlags);
  298.  
  299.     if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  300.         return xPRIMARY_MONITOR;
  301.  
  302.     if (IsIconic(hWnd) ?
  303.             GetWindowPlacement(hWnd, &wp) :
  304.             GetWindowRect(hWnd, &wp.rcNormalPosition)) {
  305.  
  306.         return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
  307.     }
  308.  
  309.     return NULL;
  310. }
  311.  
  312. BOOL WINAPI
  313. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  314. {
  315.     RECT rcWork;
  316.  
  317.     if (InitMultipleMonitorStubs())
  318.     {
  319.         BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  320. #ifdef UNICODE
  321.         if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
  322.         { 
  323.             MultiByteToWideChar(CP_ACP, 0,
  324.                 (LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
  325.                 ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  326.         }
  327. #endif
  328.         return f;
  329.     }
  330.  
  331.     if ((hMonitor == xPRIMARY_MONITOR) &&
  332.         lpMonitorInfo &&
  333.         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  334.         SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
  335.     {
  336.         lpMonitorInfo->rcMonitor.left = 0;
  337.         lpMonitorInfo->rcMonitor.top  = 0;
  338.         lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
  339.         lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  340.         lpMonitorInfo->rcWork = rcWork;
  341.         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  342.  
  343.         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  344.         {
  345. #ifdef UNICODE
  346.             MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  347. #else // UNICODE
  348.             lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  349. #endif // UNICODE
  350.         }
  351.  
  352.         return TRUE;
  353.     }
  354.  
  355.     return FALSE;
  356. }
  357.  
  358. BOOL WINAPI
  359. xEnumDisplayMonitors(
  360.         HDC             hdcOptionalForPainting,
  361.         LPCRECT         lprcEnumMonitorsThatIntersect,
  362.         MONITORENUMPROC lpfnEnumProc,
  363.         LPARAM          dwData)
  364. {
  365.     RECT rcLimit;
  366.  
  367.     if (InitMultipleMonitorStubs()) {
  368.         return g_pfnEnumDisplayMonitors(
  369.                 hdcOptionalForPainting,
  370.                 lprcEnumMonitorsThatIntersect,
  371.                 lpfnEnumProc,
  372.                 dwData);
  373.     }
  374.  
  375.     if (!lpfnEnumProc)
  376.         return FALSE;
  377.  
  378.     rcLimit.left   = 0;
  379.     rcLimit.top    = 0;
  380.     rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
  381.     rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  382.  
  383.     if (hdcOptionalForPainting)
  384.     {
  385.         RECT    rcClip;
  386.         POINT   ptOrg;
  387.  
  388.         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  389.         {
  390.         default:
  391.             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
  392.                 return FALSE;
  393.  
  394.             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
  395.             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
  396.                 (!lprcEnumMonitorsThatIntersect ||
  397.                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
  398.  
  399.                 break;
  400.             }
  401.             //fall thru
  402.         case NULLREGION:
  403.              return TRUE;
  404.         case ERROR:
  405.              return FALSE;
  406.         }
  407.     } else {
  408.         if (    lprcEnumMonitorsThatIntersect &&
  409.                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
  410.  
  411.             return TRUE;
  412.         }
  413.     }
  414.  
  415.     return lpfnEnumProc(
  416.             xPRIMARY_MONITOR,
  417.             hdcOptionalForPainting,
  418.             &rcLimit,
  419.             dwData);
  420. }
  421.  
  422. BOOL WINAPI
  423. xEnumDisplayDevices(
  424.     PVOID Unused,
  425.     DWORD iDevNum,
  426.     PDISPLAY_DEVICE lpDisplayDevice,
  427.     DWORD dwFlags)
  428. {
  429.     if (InitMultipleMonitorStubs())
  430.         return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);
  431.  
  432.     if (Unused != NULL)
  433.         return FALSE;
  434.  
  435.     if (iDevNum != 0)
  436.         return FALSE;
  437.  
  438.     if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
  439.         return FALSE;
  440.  
  441. #ifdef UNICODE
  442.     MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  443.     MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  444. #else // UNICODE
  445.     lstrcpy((LPTSTR)lpDisplayDevice->DeviceName,   TEXT("DISPLAY"));
  446.     lstrcpy((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"));
  447. #endif // UNICODE
  448.  
  449.     lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
  450.  
  451.     return TRUE;
  452. }
  453.  
  454. #undef xPRIMARY_MONITOR
  455. #undef COMPILE_MULTIMON_STUBS
  456.  
  457. #else   // COMPILE_MULTIMON_STUBS
  458.  
  459. extern int  WINAPI xGetSystemMetrics(int);
  460. extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
  461. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
  462. extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
  463. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  464. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  465. extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
  466.  
  467. #endif  // COMPILE_MULTIMON_STUBS
  468.  
  469. //
  470. // build defines that replace the regular APIs with our versions
  471. //
  472. #define GetSystemMetrics    xGetSystemMetrics
  473. #define MonitorFromWindow   xMonitorFromWindow
  474. #define MonitorFromRect     xMonitorFromRect
  475. #define MonitorFromPoint    xMonitorFromPoint
  476. #define GetMonitorInfo      xGetMonitorInfo
  477. #define EnumDisplayMonitors xEnumDisplayMonitors
  478. #define EnumDisplayDevices  xEnumDisplayDevices
  479.  
  480. #ifdef __cplusplus
  481. }
  482. #endif  // __cplusplus
  483.  
  484.