home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / stretch3 / multimon.h < prev    next >
C/C++ Source or Header  |  1997-07-14  |  10KB  |  344 lines

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