1 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) 2 3 //============================================================================= 4 // 5 // MULTIMON 6 // stub module that "stubs" 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 correct 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 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 68 69 typedef struct { 70 DWORD cb; 71 CHAR DeviceName[32]; 72 CHAR DeviceString[128]; 73 DWORD StateFlags; 74 } DISPLAY_DEVICE; 75 76 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 77 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 78 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 79 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 80 81 #endif 82 #define DISPLAY_DEVICE_VGA 0x00000010 83 84 #ifndef ENUM_CURRENT_SETTINGS 85 #define ENUM_CURRENT_SETTINGS ((DWORD)-1) 86 #define ENUM_REGISTRY_SETTINGS ((DWORD)-2) 87 #endif 88 89 #undef GetMonitorInfo 90 #undef GetSystemMetrics 91 #undef MonitorFromWindow 92 #undef MonitorFromRect 93 #undef MonitorFromPoint 94 #undef EnumDisplayMonitors 95 #undef EnumDisplayDevices 96 97 // 98 // define this to compile the stubs 99 // otherwise you get the declarations 100 // 101 #ifdef COMPILE_MULTIMON_STUBS 102 103 //--------------------------------------------------------------------------- 104 // 105 // Implement the API stubs. 106 // 107 //--------------------------------------------------------------------------- 108 109 int (WINAPI* g_pfnGetSystemMetrics)(int); 110 HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, BOOL); 111 HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, BOOL); 112 HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, BOOL); 113 BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO); 114 BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, 115 MONITORENUMPROC, LPARAM); 116 BOOL (WINAPI *g_pfnEnumDisplayDevices)(LPVOID, int, 117 DISPLAY_DEVICE *,DWORD); 118 InitMultipleMonitorStubs(void)119 BOOL InitMultipleMonitorStubs(void) 120 { 121 HMODULE hUser32; 122 static BOOL fInitDone; 123 124 if (fInitDone) 125 { 126 return g_pfnGetMonitorInfo != NULL; 127 } 128 129 if ((hUser32 = GetModuleHandle(TEXT("USER32"))) && 130 (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) && 131 (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) && 132 (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) && 133 (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) && 134 (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) && 135 #ifdef UNICODE 136 (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoW")) && 137 (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) && 138 #else 139 (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) && 140 (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) && 141 #endif 142 (GetSystemMetrics(SM_CXVIRTUALSCREEN) >= GetSystemMetrics(SM_CXSCREEN)) && 143 (GetSystemMetrics(SM_CYVIRTUALSCREEN) >= GetSystemMetrics(SM_CYSCREEN)) ) 144 { 145 fInitDone = TRUE; 146 return TRUE; 147 } 148 else 149 { 150 g_pfnGetSystemMetrics = NULL; 151 g_pfnMonitorFromWindow = NULL; 152 g_pfnMonitorFromRect = NULL; 153 g_pfnMonitorFromPoint = NULL; 154 g_pfnGetMonitorInfo = NULL; 155 g_pfnEnumDisplayMonitors = NULL; 156 g_pfnEnumDisplayDevices = NULL; 157 158 fInitDone = TRUE; 159 return FALSE; 160 } 161 } 162 163 //--------------------------------------------------------------------------- 164 // 165 // "stubbed" implementations of Monitor APIs that work with the primary // display 166 // 167 //--------------------------------------------------------------------------- 168 169 int WINAPI xGetSystemMetrics(int nIndex)170 xGetSystemMetrics(int nIndex) 171 { 172 if (InitMultipleMonitorStubs()) 173 return g_pfnGetSystemMetrics(nIndex); 174 175 switch (nIndex) 176 { 177 case SM_CMONITORS: 178 case SM_SAMEDISPLAYFORMAT: 179 return 1; 180 181 case SM_XVIRTUALSCREEN: 182 case SM_YVIRTUALSCREEN: 183 return 0; 184 185 case SM_CXVIRTUALSCREEN: 186 nIndex = SM_CXSCREEN; 187 break; 188 189 case SM_CYVIRTUALSCREEN: 190 nIndex = SM_CYSCREEN; 191 break; 192 } 193 194 return GetSystemMetrics(nIndex); 195 } 196 197 #define xPRIMARY_MONITOR ((HMONITOR)0x42) 198 199 HMONITOR WINAPI xMonitorFromRect(LPCRECT lprcScreenCoords,UINT uFlags)200 xMonitorFromRect(LPCRECT lprcScreenCoords, UINT uFlags) 201 { 202 if (InitMultipleMonitorStubs()) 203 return g_pfnMonitorFromRect(lprcScreenCoords, uFlags); 204 205 if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || 206 ((lprcScreenCoords->right > 0) && 207 (lprcScreenCoords->bottom > 0) && 208 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) && 209 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN)))) 210 { 211 return xPRIMARY_MONITOR; 212 } 213 214 return NULL; 215 } 216 217 HMONITOR WINAPI xMonitorFromWindow(HWND hWnd,UINT uFlags)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 HMONITOR WINAPI xMonitorFromPoint(POINT ptScreenCoords,UINT uFlags)235 xMonitorFromPoint(POINT ptScreenCoords, UINT uFlags) 236 { 237 if (InitMultipleMonitorStubs()) 238 return g_pfnMonitorFromPoint(ptScreenCoords, uFlags); 239 240 if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || 241 ((ptScreenCoords.x >= 0) && 242 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) && 243 (ptScreenCoords.y >= 0) && 244 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN)))) 245 { 246 return xPRIMARY_MONITOR; 247 } 248 249 return NULL; 250 } 251 252 BOOL WINAPI xGetMonitorInfo(HMONITOR hMonitor,LPMONITORINFO lpMonitorInfo)253 xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo) 254 { 255 RECT rcWork; 256 257 if (InitMultipleMonitorStubs()) 258 return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo); 259 260 if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo && 261 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) && 262 SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0)) 263 { 264 lpMonitorInfo->rcMonitor.left = 0; 265 lpMonitorInfo->rcMonitor.top = 0; 266 lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN); 267 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN); 268 lpMonitorInfo->rcWork = rcWork; 269 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; 270 271 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)) 272 lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, 273 TEXT("DISPLAY")); 274 275 return TRUE; 276 } 277 278 return FALSE; 279 } 280 281 BOOL WINAPI xEnumDisplayMonitors(HDC hdc,LPCRECT lprcIntersect,MONITORENUMPROC lpfnEnumProc,LPARAM lData)282 xEnumDisplayMonitors( 283 HDC hdc, 284 LPCRECT lprcIntersect, 285 MONITORENUMPROC lpfnEnumProc, 286 LPARAM lData) 287 { 288 RECT rcCallback, rcLimit; 289 290 if (InitMultipleMonitorStubs()) 291 return g_pfnEnumDisplayMonitors(hdc, lprcIntersect, lpfnEnumProc, 292 lData); 293 294 if (!lpfnEnumProc) 295 return FALSE; 296 297 rcLimit.left = 0; 298 rcLimit.top = 0; 299 rcLimit.right = GetSystemMetrics(SM_CXSCREEN); 300 rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN); 301 302 if (hdc) 303 { 304 RECT rcClip; 305 HWND hWnd; 306 307 if ((hWnd = WindowFromDC(hdc)) == NULL) 308 return FALSE; 309 310 switch (GetClipBox(hdc, &rcClip)) 311 { 312 default: 313 MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2); 314 if (IntersectRect(&rcCallback, &rcClip, &rcLimit)) 315 break; 316 //fall thru 317 case NULLREGION: 318 return TRUE; 319 case ERROR: 320 return FALSE; 321 } 322 323 rcLimit = rcCallback; 324 } 325 326 if (!lprcIntersect || 327 IntersectRect(&rcCallback, lprcIntersect, &rcLimit)) 328 { 329 lpfnEnumProc(xPRIMARY_MONITOR, hdc, &rcCallback, lData); 330 } 331 332 return TRUE; 333 } 334 335 BOOL WINAPI xEnumDisplayDevices(LPVOID lpReserved,int iDeviceNum,DISPLAY_DEVICE * pDisplayDevice,DWORD dwFlags)336 xEnumDisplayDevices(LPVOID lpReserved, int iDeviceNum, 337 DISPLAY_DEVICE * pDisplayDevice, DWORD dwFlags) 338 { 339 if (InitMultipleMonitorStubs()) 340 return g_pfnEnumDisplayDevices(lpReserved, iDeviceNum, 341 pDisplayDevice, dwFlags); 342 343 return FALSE; 344 } 345 346 #undef xPRIMARY_MONITOR 347 #undef COMPILE_MULTIMON_STUBS 348 349 #else // COMPILE_MULTIMON_STUBS 350 351 extern int WINAPI xGetSystemMetrics(int); 352 extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT); 353 extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT); 354 extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT); 355 extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO); 356 extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, 357 LPARAM); 358 extern BOOL WINAPI xEnumDisplayDevices(LPVOID, int, DISPLAY_DEVICE *,DWORD); 359 360 #endif // COMPILE_MULTIMON_STUBS 361 362 // 363 // build defines that replace the regular APIs with our versions 364 // 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 372 373 #ifdef __cplusplus 374 } 375 #endif /* __cplusplus */ 376 377 #endif /* !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) */ 378