6 //=============================================================================
\r
9 // stub module that "stubs" multiple monitor APIs on pre-Memphis Win32 OSes
\r
11 // By using this header your code will work unchanged on Win95,
\r
12 // you will get back correct values from GetSystemMetrics() for new metrics
\r
13 // and the new APIs will act like only one display is present.
\r
15 // exactly one source must include this with COMPILE_MULTIMON_STUBS defined
\r
17 //=============================================================================
\r
20 extern "C" { /* Assume C declarations for C++ */
\r
21 #endif /* __cplusplus */
\r
24 // if we are building on Win95/NT4 headers we need to declare this stuff ourselves
\r
26 #ifndef SM_CMONITORS
\r
28 #define SM_XVIRTUALSCREEN 76
\r
29 #define SM_YVIRTUALSCREEN 77
\r
30 #define SM_CXVIRTUALSCREEN 78
\r
31 #define SM_CYVIRTUALSCREEN 79
\r
32 #define SM_CMONITORS 80
\r
33 #define SM_SAMEDISPLAYFORMAT 81
\r
35 DECLARE_HANDLE(HMONITOR);
\r
37 #define MONITOR_DEFAULTTONULL 0x00000000
\r
38 #define MONITOR_DEFAULTTOPRIMARY 0x00000001
\r
39 #define MONITOR_DEFAULTTONEAREST 0x00000002
\r
41 #define MONITORINFOF_PRIMARY 0x00000001
\r
43 typedef struct tagMONITORINFO
\r
49 } MONITORINFO, *LPMONITORINFO;
\r
51 #define CCHDEVICENAME 32
\r
54 typedef struct tagMONITORINFOEX : public tagMONITORINFO
\r
56 TCHAR szDevice[CCHDEVICENAME];
\r
57 } MONITORINFOEX, *LPMONITORINFOEX;
\r
62 TCHAR szDevice[CCHDEVICENAME];
\r
63 } MONITORINFOEX, *LPMONITORINFOEX;
\r
66 typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
\r
68 #endif // SM_CMONITORS
\r
70 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
\r
74 CHAR DeviceName[32];
\r
75 CHAR DeviceString[128];
\r
79 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
\r
80 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
\r
81 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
\r
82 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
\r
85 #define DISPLAY_DEVICE_VGA 0x00000010
\r
87 #ifndef ENUM_CURRENT_SETTINGS
\r
88 #define ENUM_CURRENT_SETTINGS ((DWORD)-1)
\r
89 #define ENUM_REGISTRY_SETTINGS ((DWORD)-2)
\r
92 #undef GetMonitorInfo
\r
93 #undef GetSystemMetrics
\r
94 #undef MonitorFromWindow
\r
95 #undef MonitorFromRect
\r
96 #undef MonitorFromPoint
\r
97 #undef EnumDisplayMonitors
\r
98 #undef EnumDisplayDevices
\r
101 // define this to compile the stubs
\r
102 // otherwise you get the declarations
\r
104 #ifdef COMPILE_MULTIMON_STUBS
\r
106 //---------------------------------------------------------------------------
\r
108 // Implement the API stubs.
\r
110 //---------------------------------------------------------------------------
\r
112 int (WINAPI* g_pfnGetSystemMetrics)(int);
\r
113 HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, BOOL);
\r
114 HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, BOOL);
\r
115 HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, BOOL);
\r
116 BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO);
\r
117 BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
\r
118 BOOL (WINAPI *g_pfnEnumDisplayDevices)(LPVOID, int, DISPLAY_DEVICE *, DWORD);
\r
120 BOOL InitMultipleMonitorStubs(void)
\r
123 static BOOL fInitDone;
\r
127 return g_pfnGetMonitorInfo != NULL;
\r
130 if ((hUser32 = GetModuleHandle(TEXT("USER32"))) &&
\r
131 (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) &&
\r
132 (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) &&
\r
133 (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) &&
\r
134 (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) &&
\r
135 (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) &&
\r
137 (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoW")) &&
\r
138 (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) &&
\r
140 (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) &&
\r
141 (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) &&
\r
143 (GetSystemMetrics(SM_CXVIRTUALSCREEN) >= GetSystemMetrics(SM_CXSCREEN)) &&
\r
144 (GetSystemMetrics(SM_CYVIRTUALSCREEN) >= GetSystemMetrics(SM_CYSCREEN)) )
\r
151 g_pfnGetSystemMetrics = NULL;
\r
152 g_pfnMonitorFromWindow = NULL;
\r
153 g_pfnMonitorFromRect = NULL;
\r
154 g_pfnMonitorFromPoint = NULL;
\r
155 g_pfnGetMonitorInfo = NULL;
\r
156 g_pfnEnumDisplayMonitors = NULL;
\r
157 g_pfnEnumDisplayDevices = NULL;
\r
164 //---------------------------------------------------------------------------
\r
166 // "stubbed" implementations of Monitor APIs that work with the primary // display
\r
168 //---------------------------------------------------------------------------
\r
171 xGetSystemMetrics(int nIndex)
\r
173 if (InitMultipleMonitorStubs())
\r
174 return g_pfnGetSystemMetrics(nIndex);
\r
179 case SM_SAMEDISPLAYFORMAT:
\r
182 case SM_XVIRTUALSCREEN:
\r
183 case SM_YVIRTUALSCREEN:
\r
186 case SM_CXVIRTUALSCREEN:
\r
187 nIndex = SM_CXSCREEN;
\r
190 case SM_CYVIRTUALSCREEN:
\r
191 nIndex = SM_CYSCREEN;
\r
195 return GetSystemMetrics(nIndex);
\r
198 #define xPRIMARY_MONITOR ((HMONITOR)0x42)
\r
201 xMonitorFromRect(LPCRECT lprcScreenCoords,
\r
204 if (InitMultipleMonitorStubs())
\r
205 return g_pfnMonitorFromRect(lprcScreenCoords, uFlags);
\r
207 if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
\r
208 ((lprcScreenCoords->right > 0) &&
\r
209 (lprcScreenCoords->bottom > 0) &&
\r
210 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
\r
211 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
\r
213 return xPRIMARY_MONITOR;
\r
220 xMonitorFromWindow(HWND hWnd,
\r
225 if (InitMultipleMonitorStubs())
\r
226 return g_pfnMonitorFromWindow(hWnd, uFlags);
\r
228 if (uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
\r
229 return xPRIMARY_MONITOR;
\r
231 if (GetWindowRect(hWnd, &rc))
\r
232 return xMonitorFromRect(&rc, uFlags);
\r
238 xMonitorFromPoint(POINT ptScreenCoords,
\r
241 if (InitMultipleMonitorStubs())
\r
242 return g_pfnMonitorFromPoint(ptScreenCoords, uFlags);
\r
244 if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
\r
245 ((ptScreenCoords.x >= 0) &&
\r
246 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
\r
247 (ptScreenCoords.y >= 0) &&
\r
248 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
\r
250 return xPRIMARY_MONITOR;
\r
257 xGetMonitorInfo(HMONITOR hMonitor,
\r
258 LPMONITORINFO lpMonitorInfo)
\r
262 if (InitMultipleMonitorStubs())
\r
263 return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
\r
265 if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo &&
\r
266 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
\r
267 SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))
\r
269 lpMonitorInfo->rcMonitor.left = 0;
\r
270 lpMonitorInfo->rcMonitor.top = 0;
\r
271 lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
\r
272 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
\r
273 lpMonitorInfo->rcWork = rcWork;
\r
274 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
\r
276 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
\r
277 lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice,
\r
287 xEnumDisplayMonitors(HDC hdc,
\r
288 LPCRECT lprcIntersect,
\r
289 MONITORENUMPROC lpfnEnumProc,
\r
292 RECT rcCallback, rcLimit;
\r
294 if (InitMultipleMonitorStubs())
\r
295 return g_pfnEnumDisplayMonitors(hdc, lprcIntersect, lpfnEnumProc, lData);
\r
302 rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
\r
303 rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
\r
310 if ((hWnd = WindowFromDC(hdc)) == NULL)
\r
313 switch (GetClipBox(hdc, &rcClip))
\r
316 MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);
\r
317 if (IntersectRect(&rcCallback, &rcClip, &rcLimit))
\r
326 rcLimit = rcCallback;
\r
329 if (!lprcIntersect || IntersectRect(&rcCallback, lprcIntersect, &rcLimit))
\r
331 lpfnEnumProc(xPRIMARY_MONITOR, hdc, &rcCallback, lData);
\r
338 xEnumDisplayDevices(LPVOID lpReserved,
\r
340 DISPLAY_DEVICE * pDisplayDevice,
\r
343 if (InitMultipleMonitorStubs())
\r
344 return g_pfnEnumDisplayDevices(lpReserved, iDeviceNum, pDisplayDevice, dwFlags);
\r
349 #undef xPRIMARY_MONITOR
\r
350 #undef COMPILE_MULTIMON_STUBS
\r
352 #else // COMPILE_MULTIMON_STUBS
\r
354 extern int WINAPI xGetSystemMetrics(int);
\r
355 extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);
\r
356 extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);
\r
357 extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);
\r
358 extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
\r
359 extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
\r
360 extern BOOL WINAPI xEnumDisplayDevices(LPVOID, int, DISPLAY_DEVICE *, DWORD);
\r
362 #endif // COMPILE_MULTIMON_STUBS
\r
365 // build defines that replace the regular APIs with our versions
\r
367 #define GetSystemMetrics xGetSystemMetrics
\r
368 #define MonitorFromWindow xMonitorFromWindow
\r
369 #define MonitorFromRect xMonitorFromRect
\r
370 #define MonitorFromPoint xMonitorFromPoint
\r
371 #define GetMonitorInfo xGetMonitorInfo
\r
372 #define EnumDisplayMonitors xEnumDisplayMonitors
\r
373 #define EnumDisplayDevices xEnumDisplayDevices
\r
377 #endif // __cplusplus
\r
381 #endif // __MULTIMON_H