6 //=============================================================================
9 // stub module that "stubs" multiple monitor APIs on pre-Memphis Win32 OSes
11 // By using this header your code will work unchanged on Win95,
12 // you will get back correct values from GetSystemMetrics() for new metrics
13 // and the new APIs will act like only one display is present.
15 // exactly one source must include this with COMPILE_MULTIMON_STUBS defined
17 //=============================================================================
20 extern "C" { /* Assume C declarations for C++ */
21 #endif /* __cplusplus */
24 // if we are building on Win95/NT4 headers we need to declare this stuff ourselves
28 #define SM_XVIRTUALSCREEN 76
29 #define SM_YVIRTUALSCREEN 77
30 #define SM_CXVIRTUALSCREEN 78
31 #define SM_CYVIRTUALSCREEN 79
32 #define SM_CMONITORS 80
33 #define SM_SAMEDISPLAYFORMAT 81
35 DECLARE_HANDLE( HMONITOR );
37 #define MONITOR_DEFAULTTONULL 0x00000000
38 #define MONITOR_DEFAULTTOPRIMARY 0x00000001
39 #define MONITOR_DEFAULTTONEAREST 0x00000002
41 #define MONITORINFOF_PRIMARY 0x00000001
43 typedef struct tagMONITORINFO
49 } MONITORINFO, *LPMONITORINFO;
51 #define CCHDEVICENAME 32
54 typedef struct tagMONITORINFOEX : public tagMONITORINFO
56 TCHAR szDevice[CCHDEVICENAME];
57 } MONITORINFOEX, *LPMONITORINFOEX;
62 TCHAR szDevice[CCHDEVICENAME];
63 } MONITORINFOEX, *LPMONITORINFOEX;
66 typedef BOOL ( CALLBACK * MONITORENUMPROC )( HMONITOR, HDC, LPRECT, LPARAM );
68 #endif // SM_CMONITORS
70 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
75 CHAR DeviceString[128];
79 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
80 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
81 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
82 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
85 #define DISPLAY_DEVICE_VGA 0x00000010
87 #ifndef ENUM_CURRENT_SETTINGS
88 #define ENUM_CURRENT_SETTINGS ( (DWORD)-1 )
89 #define ENUM_REGISTRY_SETTINGS ( (DWORD)-2 )
93 #undef GetSystemMetrics
94 #undef MonitorFromWindow
95 #undef MonitorFromRect
96 #undef MonitorFromPoint
97 #undef EnumDisplayMonitors
98 #undef EnumDisplayDevices
101 // define this to compile the stubs
102 // otherwise you get the declarations
104 #ifdef COMPILE_MULTIMON_STUBS
106 //---------------------------------------------------------------------------
108 // Implement the API stubs.
110 //---------------------------------------------------------------------------
112 int ( WINAPI* g_pfnGetSystemMetrics )( int );
113 HMONITOR ( WINAPI* g_pfnMonitorFromWindow )( HWND, BOOL );
114 HMONITOR ( WINAPI* g_pfnMonitorFromRect )( LPCRECT, BOOL );
115 HMONITOR ( WINAPI* g_pfnMonitorFromPoint )( POINT, BOOL );
116 BOOL ( WINAPI* g_pfnGetMonitorInfo )( HMONITOR, LPMONITORINFO );
117 BOOL ( WINAPI* g_pfnEnumDisplayMonitors )( HDC, LPCRECT, MONITORENUMPROC, LPARAM );
118 BOOL ( WINAPI *g_pfnEnumDisplayDevices )( LPVOID, int, DISPLAY_DEVICE *, DWORD );
120 BOOL InitMultipleMonitorStubs( void ){
122 static BOOL fInitDone;
125 return g_pfnGetMonitorInfo != NULL;
128 if ( ( hUser32 = GetModuleHandle( TEXT( "USER32" ) ) ) &&
129 ( *(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress( hUser32,"GetSystemMetrics" ) ) &&
130 ( *(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress( hUser32,"MonitorFromWindow" ) ) &&
131 ( *(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress( hUser32,"MonitorFromRect" ) ) &&
132 ( *(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress( hUser32,"MonitorFromPoint" ) ) &&
133 ( *(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress( hUser32,"EnumDisplayMonitors" ) ) &&
135 ( *(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress( hUser32,"GetMonitorInfoW" ) ) &&
136 ( *(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress( hUser32,"EnumDisplayDevicesW" ) ) &&
138 ( *(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress( hUser32,"GetMonitorInfoA" ) ) &&
139 ( *(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress( hUser32,"EnumDisplayDevicesA" ) ) &&
141 ( GetSystemMetrics( SM_CXVIRTUALSCREEN ) >= GetSystemMetrics( SM_CXSCREEN ) ) &&
142 ( GetSystemMetrics( SM_CYVIRTUALSCREEN ) >= GetSystemMetrics( SM_CYSCREEN ) ) ) {
148 g_pfnGetSystemMetrics = NULL;
149 g_pfnMonitorFromWindow = NULL;
150 g_pfnMonitorFromRect = NULL;
151 g_pfnMonitorFromPoint = NULL;
152 g_pfnGetMonitorInfo = NULL;
153 g_pfnEnumDisplayMonitors = NULL;
154 g_pfnEnumDisplayDevices = NULL;
161 //---------------------------------------------------------------------------
163 // "stubbed" implementations of Monitor APIs that work with the primary // display
165 //---------------------------------------------------------------------------
168 xGetSystemMetrics( int nIndex ){
169 if ( InitMultipleMonitorStubs() ) {
170 return g_pfnGetSystemMetrics( nIndex );
176 case SM_SAMEDISPLAYFORMAT:
179 case SM_XVIRTUALSCREEN:
180 case SM_YVIRTUALSCREEN:
183 case SM_CXVIRTUALSCREEN:
184 nIndex = SM_CXSCREEN;
187 case SM_CYVIRTUALSCREEN:
188 nIndex = SM_CYSCREEN;
192 return GetSystemMetrics( nIndex );
195 #define xPRIMARY_MONITOR ( (HMONITOR)0x42 )
198 xMonitorFromRect( LPCRECT lprcScreenCoords,
200 if ( InitMultipleMonitorStubs() ) {
201 return g_pfnMonitorFromRect( lprcScreenCoords, uFlags );
204 if ( ( uFlags & ( MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST ) ) ||
205 ( ( lprcScreenCoords->right > 0 ) &&
206 ( lprcScreenCoords->bottom > 0 ) &&
207 ( lprcScreenCoords->left < GetSystemMetrics( SM_CXSCREEN ) ) &&
208 ( lprcScreenCoords->top < GetSystemMetrics( SM_CYSCREEN ) ) ) ) {
209 return xPRIMARY_MONITOR;
216 xMonitorFromWindow( HWND hWnd,
220 if ( InitMultipleMonitorStubs() ) {
221 return g_pfnMonitorFromWindow( hWnd, uFlags );
224 if ( uFlags & ( MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST ) ) {
225 return xPRIMARY_MONITOR;
228 if ( GetWindowRect( hWnd, &rc ) ) {
229 return xMonitorFromRect( &rc, uFlags );
236 xMonitorFromPoint( POINT ptScreenCoords,
238 if ( InitMultipleMonitorStubs() ) {
239 return g_pfnMonitorFromPoint( ptScreenCoords, uFlags );
242 if ( ( uFlags & ( MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST ) ) ||
243 ( ( ptScreenCoords.x >= 0 ) &&
244 ( ptScreenCoords.x < GetSystemMetrics( SM_CXSCREEN ) ) &&
245 ( ptScreenCoords.y >= 0 ) &&
246 ( ptScreenCoords.y < GetSystemMetrics( SM_CYSCREEN ) ) ) ) {
247 return xPRIMARY_MONITOR;
254 xGetMonitorInfo( HMONITOR hMonitor,
255 LPMONITORINFO lpMonitorInfo ){
258 if ( InitMultipleMonitorStubs() ) {
259 return g_pfnGetMonitorInfo( hMonitor, lpMonitorInfo );
262 if ( ( hMonitor == xPRIMARY_MONITOR ) && lpMonitorInfo &&
263 ( lpMonitorInfo->cbSize >= sizeof( MONITORINFO ) ) &&
264 SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 ) ) {
265 lpMonitorInfo->rcMonitor.left = 0;
266 lpMonitorInfo->rcMonitor.top = 0;
267 lpMonitorInfo->rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
268 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
269 lpMonitorInfo->rcWork = rcWork;
270 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
272 if ( lpMonitorInfo->cbSize >= sizeof( MONITORINFOEX ) ) {
273 lstrcpy( ( (MONITORINFOEX*)lpMonitorInfo )->szDevice,
284 xEnumDisplayMonitors( HDC hdc,
285 LPCRECT lprcIntersect,
286 MONITORENUMPROC lpfnEnumProc,
288 RECT rcCallback, rcLimit;
290 if ( InitMultipleMonitorStubs() ) {
291 return g_pfnEnumDisplayMonitors( hdc, lprcIntersect, lpfnEnumProc, lData );
294 if ( !lpfnEnumProc ) {
300 rcLimit.right = GetSystemMetrics( SM_CXSCREEN );
301 rcLimit.bottom = GetSystemMetrics( SM_CYSCREEN );
307 if ( ( hWnd = WindowFromDC( hdc ) ) == NULL ) {
311 switch ( GetClipBox( hdc, &rcClip ) )
314 MapWindowPoints( NULL, hWnd, (LPPOINT)&rcLimit, 2 );
315 if ( IntersectRect( &rcCallback, &rcClip, &rcLimit ) ) {
325 rcLimit = rcCallback;
328 if ( !lprcIntersect || IntersectRect( &rcCallback, lprcIntersect, &rcLimit ) ) {
329 lpfnEnumProc( xPRIMARY_MONITOR, hdc, &rcCallback, lData );
336 xEnumDisplayDevices( LPVOID lpReserved,
338 DISPLAY_DEVICE * pDisplayDevice,
340 if ( InitMultipleMonitorStubs() ) {
341 return g_pfnEnumDisplayDevices( lpReserved, iDeviceNum, pDisplayDevice, dwFlags );
347 #undef xPRIMARY_MONITOR
348 #undef COMPILE_MULTIMON_STUBS
350 #else // COMPILE_MULTIMON_STUBS
352 extern int WINAPI xGetSystemMetrics( int );
353 extern HMONITOR WINAPI xMonitorFromWindow( HWND, UINT );
354 extern HMONITOR WINAPI xMonitorFromRect( LPCRECT, UINT );
355 extern HMONITOR WINAPI xMonitorFromPoint( POINT, UINT );
356 extern BOOL WINAPI xGetMonitorInfo( HMONITOR, LPMONITORINFO );
357 extern BOOL WINAPI xEnumDisplayMonitors( HDC, LPCRECT, MONITORENUMPROC, LPARAM );
358 extern BOOL WINAPI xEnumDisplayDevices( LPVOID, int, DISPLAY_DEVICE *, DWORD );
360 #endif // COMPILE_MULTIMON_STUBS
363 // build defines that replace the regular APIs with our versions
365 #define GetSystemMetrics xGetSystemMetrics
366 #define MonitorFromWindow xMonitorFromWindow
367 #define MonitorFromRect xMonitorFromRect
368 #define MonitorFromPoint xMonitorFromPoint
369 #define GetMonitorInfo xGetMonitorInfo
370 #define EnumDisplayMonitors xEnumDisplayMonitors
371 #define EnumDisplayDevices xEnumDisplayDevices
375 #endif // __cplusplus
379 #endif // __MULTIMON_H