home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / multimon.h < prev    next >
C/C++ Source or Header  |  1998-04-25  |  11KB  |  361 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-1996, 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 _WIN32_WINNT >= 0x0500 in windef.h
  35. // This is for components built with an older version number.
  36. //
  37. #if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 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 tagMONITORINFOEX : public tagMONITORINFO
  62. {
  63.     TCHAR       szDevice[CCHDEVICENAME];
  64. } MONITORINFOEX, *LPMONITORINFOEX;
  65. #else
  66. typedef struct
  67. {
  68.     MONITORINFO;
  69.     TCHAR       szDevice[CCHDEVICENAME];
  70. } MONITORINFOEX, *LPMONITORINFOEX;
  71. #endif
  72.  
  73. typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
  74.  
  75. #endif  // SM_CMONITORS
  76.  
  77. #undef GetMonitorInfo
  78. #undef GetSystemMetrics
  79. #undef MonitorFromWindow
  80. #undef MonitorFromRect
  81. #undef MonitorFromPoint
  82. #undef EnumDisplayMonitors
  83.  
  84. //
  85. // Define COMPILE_MULTIMON_STUBS to compile the stubs;
  86. // otherwise, you get the declarations.
  87. //
  88. #ifdef COMPILE_MULTIMON_STUBS
  89.  
  90. //-----------------------------------------------------------------------------
  91. //
  92. // Implement the API stubs.
  93. //
  94. //-----------------------------------------------------------------------------
  95.  
  96. #ifndef MULTIMON_FNS_DEFINED
  97.  
  98. int      (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
  99. HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
  100. HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
  101. HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
  102. BOOL     (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
  103. BOOL     (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
  104. BOOL     g_fMultiMonInitDone = FALSE;
  105.  
  106. #endif
  107.  
  108. BOOL InitMultipleMonitorStubs(void)
  109. {
  110.     HMODULE hUser32;
  111.  
  112.     if (g_fMultiMonInitDone)
  113.     {
  114.         return g_pfnGetMonitorInfo != NULL;
  115.     }
  116.  
  117.     if ((hUser32 = GetModuleHandle(TEXT("USER32"))) &&
  118.         (*(FARPROC*)&g_pfnGetSystemMetrics    = GetProcAddress(hUser32,"GetSystemMetrics")) &&
  119.         (*(FARPROC*)&g_pfnMonitorFromWindow   = GetProcAddress(hUser32,"MonitorFromWindow")) &&
  120.         (*(FARPROC*)&g_pfnMonitorFromRect     = GetProcAddress(hUser32,"MonitorFromRect")) &&
  121.         (*(FARPROC*)&g_pfnMonitorFromPoint    = GetProcAddress(hUser32,"MonitorFromPoint")) &&
  122.         (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) &&
  123. #ifdef UNICODE
  124.         (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoW")) )
  125. #else
  126.         (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoA")) )
  127. #endif
  128.  
  129.     {
  130.         g_fMultiMonInitDone = TRUE;
  131.         return TRUE;
  132.     }
  133.     else
  134.     {
  135.         g_pfnGetSystemMetrics    = NULL;
  136.         g_pfnMonitorFromWindow   = NULL;
  137.         g_pfnMonitorFromRect     = NULL;
  138.         g_pfnMonitorFromPoint    = NULL;
  139.         g_pfnGetMonitorInfo      = NULL;
  140.         g_pfnEnumDisplayMonitors = NULL;
  141.  
  142.         g_fMultiMonInitDone = TRUE;
  143.         return FALSE;
  144.     }
  145. }
  146.  
  147. //-----------------------------------------------------------------------------
  148. //
  149. // fake implementations of Monitor APIs that work with the primary display
  150. // no special parameter validation is made since these run in client code
  151. //
  152. //-----------------------------------------------------------------------------
  153.  
  154. int WINAPI
  155. xGetSystemMetrics(int nIndex)
  156. {
  157.     if (InitMultipleMonitorStubs())
  158.         return g_pfnGetSystemMetrics(nIndex);
  159.  
  160.     switch (nIndex)
  161.     {
  162.     case SM_CMONITORS:
  163.     case SM_SAMEDISPLAYFORMAT:
  164.         return 1;
  165.  
  166.     case SM_XVIRTUALSCREEN:
  167.     case SM_YVIRTUALSCREEN:
  168.         return 0;
  169.  
  170.     case SM_CXVIRTUALSCREEN:
  171.         nIndex = SM_CXSCREEN;
  172.         break;
  173.  
  174.     case SM_CYVIRTUALSCREEN:
  175.         nIndex = SM_CYSCREEN;
  176.         break;
  177.     }
  178.  
  179.     return GetSystemMetrics(nIndex);
  180. }
  181.  
  182. #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
  183.  
  184. HMONITOR WINAPI
  185. xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
  186. {
  187.     if (InitMultipleMonitorStubs())
  188.         return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
  189.  
  190.     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  191.         ((ptScreenCoords.x >= 0) &&
  192.         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
  193.         (ptScreenCoords.y >= 0) &&
  194.         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
  195.     {
  196.         return xPRIMARY_MONITOR;
  197.     }
  198.  
  199.     return NULL;
  200. }
  201.  
  202. HMONITOR WINAPI
  203. xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
  204. {
  205.     if (InitMultipleMonitorStubs())
  206.         return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
  207.  
  208.     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  209.         ((lprcScreenCoords->right > 0) &&
  210.         (lprcScreenCoords->bottom > 0) &&
  211.         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  212.         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  213.     {
  214.         return xPRIMARY_MONITOR;
  215.     }
  216.  
  217.     return NULL;
  218. }
  219.  
  220. HMONITOR WINAPI
  221. xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
  222. {
  223.     WINDOWPLACEMENT wp;
  224.  
  225.     if (InitMultipleMonitorStubs())
  226.         return g_pfnMonitorFromWindow(hWnd, dwFlags);
  227.  
  228.     if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  229.         return xPRIMARY_MONITOR;
  230.  
  231.     if (IsIconic(hWnd) ? 
  232.             GetWindowPlacement(hWnd, &wp) : 
  233.             GetWindowRect(hWnd, &wp.rcNormalPosition)) {
  234.  
  235.         return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
  236.     }
  237.  
  238.     return NULL;
  239. }
  240.  
  241. BOOL WINAPI
  242. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  243. {
  244.     RECT rcWork;
  245.  
  246.     if (InitMultipleMonitorStubs())
  247.         return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  248.  
  249.     if ((hMonitor == xPRIMARY_MONITOR) &&
  250.         lpMonitorInfo &&
  251.         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  252.         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))
  253.     {
  254.         lpMonitorInfo->rcMonitor.left = 0;
  255.         lpMonitorInfo->rcMonitor.top  = 0;
  256.         lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
  257.         lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  258.         lpMonitorInfo->rcWork = rcWork;
  259.         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  260.  
  261.         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  262.             lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  263.  
  264.         return TRUE;
  265.     }
  266.  
  267.     return FALSE;
  268. }
  269.  
  270. BOOL WINAPI
  271. xEnumDisplayMonitors(
  272.         HDC             hdcOptionalForPainting,
  273.         LPCRECT         lprcEnumMonitorsThatIntersect,
  274.         MONITORENUMPROC lpfnEnumProc,
  275.         LPARAM          dwData)
  276. {
  277.     RECT rcLimit;
  278.  
  279.     if (InitMultipleMonitorStubs()) {
  280.         return g_pfnEnumDisplayMonitors(
  281.                 hdcOptionalForPainting,
  282.                 lprcEnumMonitorsThatIntersect,
  283.                 lpfnEnumProc,
  284.                 dwData);
  285.     }
  286.  
  287.     if (!lpfnEnumProc)
  288.         return FALSE;
  289.  
  290.     rcLimit.left   = 0;
  291.     rcLimit.top    = 0;
  292.     rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
  293.     rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  294.  
  295.     if (hdcOptionalForPainting)
  296.     {
  297.         RECT    rcClip;
  298.         POINT   ptOrg;
  299.  
  300.         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  301.         {
  302.         default:
  303.             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
  304.                 return FALSE;
  305.  
  306.             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
  307.             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
  308.                 (!lprcEnumMonitorsThatIntersect ||
  309.                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
  310.  
  311.                 break;
  312.             }
  313.             //fall thru
  314.         case NULLREGION:
  315.              return TRUE;
  316.         case ERROR:
  317.              return FALSE;
  318.         }
  319.     } else {
  320.         if (    lprcEnumMonitorsThatIntersect &&
  321.                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
  322.  
  323.             return TRUE;
  324.         }
  325.     }
  326.  
  327.     return lpfnEnumProc(
  328.             xPRIMARY_MONITOR,
  329.             hdcOptionalForPainting,
  330.             &rcLimit,
  331.             dwData);
  332. }
  333.  
  334. #undef xPRIMARY_MONITOR
  335. #undef COMPILE_MULTIMON_STUBS
  336.  
  337. #else   // COMPILE_MULTIMON_STUBS
  338.  
  339. extern int  WINAPI xGetSystemMetrics(int);
  340. extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
  341. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
  342. extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
  343. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  344. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  345.  
  346. #endif  // COMPILE_MULTIMON_STUBS
  347.  
  348. //
  349. // build defines that replace the regular APIs with our versions
  350. //
  351. #define GetSystemMetrics    xGetSystemMetrics
  352. #define MonitorFromWindow   xMonitorFromWindow
  353. #define MonitorFromRect     xMonitorFromRect
  354. #define MonitorFromPoint    xMonitorFromPoint
  355. #define GetMonitorInfo      xGetMonitorInfo
  356. #define EnumDisplayMonitors xEnumDisplayMonitors
  357.  
  358. #ifdef __cplusplus
  359. }
  360. #endif  // __cplusplus
  361.