00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #define Int32x32To32(x, y) ((x) * (y))
00013
00014
00015
00016
00017
00018
#ifdef _USERK_
00019
#define BEGIN_EXCEPTION_HANDLER
00020
#define END_EXCEPTION_HANDLER
00021
#define END_EXCEPTION_HANDLER_EMPTY
00022
#else // _USERK_
00023 #define BEGIN_EXCEPTION_HANDLER try {
00024 #define END_EXCEPTION_HANDLER \
00025
} except (W32ExceptionHandler(TRUE, RIP_WARNING)) { \
00026
pMonitorResult = NULL; \
00027
}
00028 #define END_EXCEPTION_HANDLER_EMPTY \
00029
} except (W32ExceptionHandler(TRUE, RIP_WARNING)) { \
00030
}
00031
#endif // _USERK_
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
PMONITOR
00056 _MonitorFromPoint(POINT pt, DWORD dwFlags)
00057 {
00058
PMONITOR pMonitor, pMonitorResult;
00059
int dx;
00060
int dy;
00061
00062 UserAssert(
dwFlags == MONITOR_DEFAULTTONULL ||
00063
dwFlags == MONITOR_DEFAULTTOPRIMARY ||
00064
dwFlags == MONITOR_DEFAULTTONEAREST);
00065
00066
if (
GetDispInfo()->
cMonitors == 1 &&
dwFlags != MONITOR_DEFAULTTONULL)
00067
return GetPrimaryMonitor();
00068
00069
switch (
dwFlags) {
00070
case MONITOR_DEFAULTTONULL:
00071
case MONITOR_DEFAULTTOPRIMARY:
00072
00073
00074
00075
00076
BEGIN_EXCEPTION_HANDLER
00077
00078
for ( pMonitor =
REBASESHAREDPTRALWAYS(
GetDispInfo()->pMonitorFirst);
00079 pMonitor;
00080 pMonitor =
REBASESHAREDPTR(pMonitor->
pMonitorNext)) {
00081
00082
if (!(pMonitor->
dwMONFlags &
MONF_VISIBLE))
00083
continue;
00084
00085
if (
PtInRect(&((
MONITOR *)pMonitor)->rcMonitor, pt)) {
00086
return pMonitor;
00087 }
00088 }
00089
00090
END_EXCEPTION_HANDLER_EMPTY
00091
00092
00093
00094
00095
switch (
dwFlags) {
00096
case MONITOR_DEFAULTTONULL:
00097
return NULL;
00098
00099
case MONITOR_DEFAULTTOPRIMARY:
00100
return GetPrimaryMonitor();
00101
00102
default:
00103 UserAssertMsg0(
FALSE,
"Logic error in _MonitorFromPoint");
00104
break;
00105 }
00106
00107
case MONITOR_DEFAULTTONEAREST:
00108
00109
#define MONITORFROMPOINTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY) \
00110
SUMSQUARESTYPE sumsquare; \
00111
SUMSQUARESTYPE leastsumsquare; \
00112
leastsumsquare = SUMSQUARESMAX; \
00113
for ( pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst); \
00114
pMonitor; \
00115
pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) { \
00116
\
00117
if (!(pMonitor->dwMONFlags & MONF_VISIBLE)) \
00118
continue; \
00119
\
00120
00121
00122 \
00123 if (pt.x < pMonitor->rcMonitor.left) { \
00124 dx = pMonitor->rcMonitor.left - pt.x; \
00125 } else if (pt.x < pMonitor->rcMonitor.right) { \
00126 dx = 0; \
00127 } else { \
00128
00129
00130 \
00131 dx = pt.x - (pMonitor->rcMonitor.right - 1); \
00132 } \
00133 \
00134
00135
00136
00137 \
00138 if ((SUMSQUARESTYPE) dx >= leastsumsquare) \
00139 continue; \
00140 \
00141
00142
00143 \
00144 if (pt.y < pMonitor->rcMonitor.top) { \
00145 dy = pMonitor->rcMonitor.top - pt.y; \
00146 } else if (pt.y < pMonitor->rcMonitor.bottom) { \
00147
00148
00149
00150 \
00151 if (dx == 0) \
00152 return pMonitor; \
00153 \
00154 dy = 0; \
00155 } else { \
00156 dy = pt.y - (pMonitor->rcMonitor.bottom - 1); \
00157 } \
00158 \
00159
00160
00161
00162
00163 \
00164 sumsquare = POINTMULTIPLY(dx, dx); \
00165 if (sumsquare >= leastsumsquare) \
00166 continue; \
00167 \
00168
00169
00170
00171 \
00172 if (sumsquare + (SUMSQUARESTYPE) dy >= leastsumsquare) \
00173 continue; \
00174 \
00175
00176
00177 \
00178 sumsquare += (SUMSQUARESTYPE) POINTMULTIPLY(dy, dy); \
00179 if (sumsquare >= leastsumsquare) \
00180 continue; \
00181 \
00182
00183
00184 \
00185 leastsumsquare = sumsquare; \
00186 pMonitorResult = pMonitor; \
00187 }
00188
00189
#if DBG
00190
pMonitorResult = (
PMONITOR) -1;
00191
#endif
00192
00193
if ( pt.x < SHRT_MIN || SHRT_MAX < pt.x ||
00194 pt.y < SHRT_MIN || SHRT_MAX < pt.y) {
00195
00196
BEGIN_EXCEPTION_HANDLER
00197
MONITORFROMPOINTALGORITHM(_UI64_MAX, ULONGLONG, Int32x32To64)
00198
END_EXCEPTION_HANDLER
00199
00200 }
else {
00201
00202
BEGIN_EXCEPTION_HANDLER
00203
MONITORFROMPOINTALGORITHM(UINT_MAX,
UINT,
Int32x32To32)
00204
END_EXCEPTION_HANDLER
00205
00206 }
00207
00208 UserAssert(pMonitorResult != (
PMONITOR) -1);
00209
return pMonitorResult;
00210
00211
default:
00212 UserAssert(0 &&
"Logic error in _MonitorFromPoint, shouldn't have gotten here.");
00213
break;
00214 }
00215
00216 UserAssert(0 &&
"Logic error in _MonitorFromPoint, shouldn't have gotten here.");
00217
return NULL;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
PMONITOR
00244
_MonitorFromRect(LPCRECT lprc, DWORD dwFlags)
00245 {
00246
PDISPLAYINFO pDispInfo;
00247
PMONITOR pMonitor, pMonitorResult;
00248 RECT rc;
00249
int area, areaMost;
00250
00251 UserAssert(
dwFlags == MONITOR_DEFAULTTONULL ||
00252
dwFlags == MONITOR_DEFAULTTOPRIMARY ||
00253
dwFlags == MONITOR_DEFAULTTONEAREST);
00254
00255
00256
00257
00258 pDispInfo =
GetDispInfo();
00259
if (pDispInfo->
cMonitors == 1 &&
dwFlags != MONITOR_DEFAULTTONULL)
00260
return GetPrimaryMonitor();
00261
00262
00263
00264
00265
if (
IsRectEmpty(lprc)) {
00266
return _MonitorFromPoint(*(LPPOINT)lprc,
dwFlags);
00267 }
00268
00269
00270
00271
00272
if ( lprc->left <= pDispInfo->
rcScreen.left &&
00273 lprc->top <= pDispInfo->
rcScreen.top &&
00274 lprc->right >= pDispInfo->
rcScreen.right &&
00275 lprc->bottom >= pDispInfo->
rcScreen.bottom) {
00276
00277
return GetPrimaryMonitor();
00278 }
00279
00280
00281
00282
00283
00284
00285
BEGIN_EXCEPTION_HANDLER
00286
00287 areaMost = 0;
00288
for ( pMonitor =
REBASESHAREDPTRALWAYS(
GetDispInfo()->pMonitorFirst);
00289 pMonitor;
00290 pMonitor =
REBASESHAREDPTR(pMonitor->
pMonitorNext)) {
00291
00292
if (!(pMonitor->
dwMONFlags &
MONF_VISIBLE))
00293
continue;
00294
00295
if (
IntersectRect(&rc, lprc, &((
MONITOR *)pMonitor)->rcMonitor)) {
00296
if (
EqualRect(&rc, lprc))
00297
return pMonitor;
00298
00299
00300
00301
00302
00303
00304
00305
00306 area = (rc.right - rc.left) * (rc.bottom - rc.top);
00307
if (area > areaMost) {
00308 areaMost = area;
00309 pMonitorResult = pMonitor;
00310 }
00311 }
00312 }
00313
00314
END_EXCEPTION_HANDLER
00315
00316 UserAssert(areaMost >= 0);
00317
if (areaMost > 0)
00318
return pMonitorResult;
00319
00320
00321
switch (
dwFlags) {
00322
case MONITOR_DEFAULTTONULL:
00323
return NULL;
00324
00325
case MONITOR_DEFAULTTOPRIMARY:
00326
return GetPrimaryMonitor();
00327
00328
case MONITOR_DEFAULTTONEAREST:
00329 {
00330
int dx, dy;
00331
00332
#define MONITORFROMRECTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY) \
00333
SUMSQUARESTYPE sumsquare; \
00334
SUMSQUARESTYPE leastsumsquare; \
00335
leastsumsquare = SUMSQUARESMAX; \
00336
for ( pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst); \
00337
pMonitor; \
00338
pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) { \
00339
\
00340
if (!(pMonitor->dwMONFlags & MONF_VISIBLE)) \
00341
continue; \
00342
\
00343
00344
00345 \
00346 if (lprc->right <= pMonitor->rcMonitor.left) { \
00347
00348
00349 \
00350 dx = pMonitor->rcMonitor.left - lprc->right + 1; \
00351 } else if (lprc->left < pMonitor->rcMonitor.right) { \
00352 dx = 0; \
00353 } else { \
00354
00355
00356 \
00357 dx = lprc->left - (pMonitor->rcMonitor.right - 1); \
00358 } \
00359 \
00360
00361
00362
00363 \
00364 if ((SUMSQUARESTYPE) dx >= leastsumsquare) \
00365 continue; \
00366 \
00367
00368
00369 \
00370 if (lprc->bottom <= pMonitor->rcMonitor.top) { \
00371
00372
00373 \
00374 dy = pMonitor->rcMonitor.top - lprc->bottom + 1; \
00375 } else if (lprc->top < pMonitor->rcMonitor.bottom) { \
00376 UserAssert(dx != 0 && "This rectangle intersects a monitor, so we shouldn't be here."); \
00377 dy = 0; \
00378 } else { \
00379
00380
00381 \
00382 dy = lprc->top - pMonitor->rcMonitor.bottom + 1; \
00383 } \
00384 \
00385
00386
00387
00388
00389 \
00390 sumsquare = POINTMULTIPLY(dx, dx); \
00391 if (sumsquare >= leastsumsquare) \
00392 continue; \
00393 \
00394
00395
00396
00397 \
00398 if (sumsquare + (SUMSQUARESTYPE) dy >= leastsumsquare) \
00399 continue; \
00400 \
00401
00402
00403 \
00404 sumsquare += (SUMSQUARESTYPE) POINTMULTIPLY(dy, dy); \
00405 if (sumsquare >= leastsumsquare) \
00406 continue; \
00407 \
00408
00409
00410 \
00411 leastsumsquare = sumsquare; \
00412 pMonitorResult = pMonitor; \
00413 }
00414
00415
#if DBG
00416
pMonitorResult = (
PMONITOR) -1;
00417
#endif
00418
00419
if ( lprc->left < SHRT_MIN || SHRT_MAX < lprc->left ||
00420 lprc->top < SHRT_MIN || SHRT_MAX < lprc->top ||
00421 lprc->right < SHRT_MIN || SHRT_MAX < lprc->right ||
00422 lprc->bottom < SHRT_MIN || SHRT_MAX < lprc->bottom) {
00423
00424
BEGIN_EXCEPTION_HANDLER
00425
MONITORFROMRECTALGORITHM(_UI64_MAX, ULONGLONG, Int32x32To64)
00426 END_EXCEPTION_HANDLER
00427
00428 } else {
00429
00430
BEGIN_EXCEPTION_HANDLER
00431
MONITORFROMRECTALGORITHM(UINT_MAX,
UINT,
Int32x32To32)
00432
END_EXCEPTION_HANDLER
00433
00434 }
00435
00436 UserAssert(pMonitorResult != (
PMONITOR) -1);
00437
return pMonitorResult;
00438 }
00439
00440
default:
00441 UserAssertMsg0(0,
"Logic error in _MonitorFromWindow, shouldn't have gotten here.");
00442
break;
00443 }
00444
00445 UserAssertMsg0(0,
"Logic error in _MonitorFromWindow, shouldn't have gotten here.");
00446
return NULL;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
PMONITOR
00475
_MonitorFromWindow(
PWND pwnd, DWORD dwFlags)
00476 {
00477
PWND pwndParent;
00478
00479 UserAssert(dwFlags == MONITOR_DEFAULTTONULL ||
00480 dwFlags == MONITOR_DEFAULTTOPRIMARY ||
00481 dwFlags == MONITOR_DEFAULTTONEAREST);
00482
00483
if (
GetDispInfo()->
cMonitors == 1 &&
dwFlags != MONITOR_DEFAULTTONULL) {
00484
return GetPrimaryMonitor();
00485 }
00486
00487
if (!pwnd)
00488
goto NoWindow;
00489
00490
00491
00492
00493
if (
TestWF(pwnd, WFMINIMIZED))
00494 {
00495
#ifdef _USERK_
00496
CHECKPOINT * pcp;
00497
00498 pcp = (
CHECKPOINT *)
_GetProp(pwnd, PROP_CHECKPOINT, PROPF_INTERNAL);
00499
if (pcp) {
00500
return _MonitorFromRect(&pcp->
rcNormal, dwFlags);
00501 }
00502
#else
00503
WINDOWPLACEMENT wp;
00504 HWND hwnd;
00505
00506 wp.length =
sizeof(wp);
00507 hwnd = (HWND)
PtoH(pwnd);
00508
if (
GetWindowPlacement(hwnd, &wp)) {
00509
return _MonitorFromRect(&wp.rcNormalPosition, dwFlags);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
if (!
IsWindow(hwnd))
00522
goto NoWindow;
00523
#endif
00524
00525 UserAssert(
GETFNID(pwnd) != FNID_DESKTOP);
00526 pwndParent =
REBASEPWND(pwnd, spwndParent);
00527
if (
GETFNID(pwndParent) ==
FNID_DESKTOP) {
00528
return GetPrimaryMonitor();
00529 }
00530
00531
00532
00533
00534
00535 }
00536
00537
return _MonitorFromRect(&((
WND *)pwnd)->rcWindow, dwFlags);
00538
00539 NoWindow:
00540
if (
dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) {
00541
return GetPrimaryMonitor();
00542 }
00543
00544
return NULL;
00545 }