MULTIMON.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  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 stupid.  (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.     
  226.     if (!lpfnEnumProc)
  227.         return FALSE;
  228.     rcLimit.left   = 0;
  229.     rcLimit.top    = 0;
  230.     rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
  231.     rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  232.     if (hdcOptionalForPainting)
  233.     {
  234.         RECT rcClip;
  235.         HWND hWnd;
  236.         if ((hWnd = WindowFromDC(hdcOptionalForPainting)) == NULL)
  237.             return FALSE;
  238.         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  239.         {
  240.         default:
  241.             MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);
  242.             if (IntersectRect(&rcCallback, &rcClip, &rcLimit))
  243.                 break;
  244.             //fall thru
  245.         case NULLREGION:
  246.              return TRUE;
  247.         case ERROR:
  248.              return FALSE;
  249.         }
  250.         rcLimit = rcCallback;
  251.     }
  252.     if (!lprcEnumMonitorsThatIntersect ||
  253.         IntersectRect(&rcCallback, lprcEnumMonitorsThatIntersect, &rcLimit))
  254.     {
  255.         lpfnEnumProc(xPRIMARY_MONITOR, hdcOptionalForPainting, &rcCallback,
  256.             lData);
  257.     }
  258.     return TRUE;
  259. }
  260. #undef xPRIMARY_MONITOR
  261. #undef COMPILE_MULTIMON_STUBS
  262. #else // COMPILE_MULTIMON_STUBS
  263. extern int WINAPI xGetSystemMetrics(int);
  264. extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);
  265. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);
  266. extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);
  267. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  268. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  269. #endif // COMPILE_MULTIMON_STUBS
  270. //
  271. // build defines that replace the regular APIs with our versions
  272. //
  273. #define GetSystemMetrics    xGetSystemMetrics
  274. #define MonitorFromWindow   xMonitorFromWindow
  275. #define MonitorFromRect     xMonitorFromRect
  276. #define MonitorFromPoint    xMonitorFromPoint
  277. #define GetMonitorInfo      xGetMonitorInfo
  278. #define EnumDisplayMonitors xEnumDisplayMonitors
  279. #ifdef __cplusplus
  280. }
  281. #endif /* __cplusplus */
  282. #endif  /* !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) */