00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
00017
00018
00019
00020
00021 __inline
BOOL LayerHitTest(
PWND pwnd, POINT pt)
00022 {
00023
ASSERT(
TestWF(pwnd,
WEFLAYERED));
00024
00025
if (
TestWF(pwnd,
WEFTRANSPARENT))
00026
return FALSE;
00027
00028
if (!GrePtInSprite(
gpDispInfo->
hDev,
PtoHq(pwnd), pt.x, pt.y))
00029
return FALSE;
00030
00031
return TRUE;
00032 }
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 PWND _ChildWindowFromPointEx(
00048
PWND pwnd,
00049 POINT pt,
00050 UINT uFlags)
00051 {
00052
if (pwnd !=
PWNDDESKTOP(pwnd)) {
00053
#ifdef USE_MIRRORING
00054
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
00055 pt.x = pwnd->
rcClient.right - pt.x;
00056 }
else
00057
#endif
00058
{
00059 pt.x += pwnd->
rcClient.left;
00060 }
00061 pt.y += pwnd->
rcClient.top;
00062 }
00063
00064
00065
00066
if (
PtInRect(&pwnd->
rcClient, pt)) {
00067
00068
PWND pwndChild;
00069
00070
if (pwnd->
hrgnClip !=
NULL) {
00071
if (!GrePtInRegion(pwnd->
hrgnClip, pt.x, pt.y))
00072
return NULL;
00073 }
00074
00075
if (
TestWF(pwnd,
WEFLAYERED)) {
00076
if (!
LayerHitTest(pwnd, pt))
00077
return NULL;
00078 }
00079
00080
00081
00082
00083
00084
for (pwndChild = pwnd->
spwndChild;
00085 pwndChild;
00086 pwndChild = pwndChild->
spwndNext) {
00087
00088
00089
00090
00091
if ((uFlags & CWP_SKIPINVISIBLE) && !
TestWF(pwndChild,
WFVISIBLE))
00092
continue;
00093
00094
if ((uFlags & CWP_SKIPDISABLED) &&
TestWF(pwndChild,
WFDISABLED))
00095
continue;
00096
00097
if ((uFlags & CWP_SKIPTRANSPARENT) &&
TestWF(pwndChild,
WEFTRANSPARENT))
00098
continue;
00099
00100
if (
PtInRect(&pwndChild->
rcWindow, pt)) {
00101
00102
if (pwndChild->
hrgnClip !=
NULL) {
00103
if (!GrePtInRegion(pwndChild->
hrgnClip, pt.x, pt.y))
00104
continue;
00105 }
00106
if (
TestWF(pwndChild,
WEFLAYERED)) {
00107
if (!
LayerHitTest(pwndChild, pt))
00108
continue;
00109 }
00110
return(pwndChild);
00111 }
00112 }
00113
00114
return pwnd;
00115 }
00116
00117
return NULL;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 PWND xxxWindowFromPoint(
00129 POINT pt)
00130 {
00131 HWND hwnd;
00132
PWND pwndT;
00133
TL tlpwndT;
00134
00135 pwndT =
_GetDesktopWindow();
00136
ThreadLock(pwndT, &tlpwndT);
00137
00138 hwnd =
xxxWindowHitTest2(pwndT, pt,
NULL,
WHT_IGNOREDISABLED);
00139
00140
ThreadUnlock(&tlpwndT);
00141
00142
return RevalidateHwnd(hwnd);
00143 }
00144
00145
#ifdef REDIRECTION
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
PWND xxxCallSpeedHitTestHook(POINT* ppt)
00157 {
00158
PHOOK pHook;
00159
PWND pwnd =
NULL;
00160
00161
00162
00163
00164
00165
if ((pHook =
PhkFirstValid(
PtiCurrent(), WH_HITTEST)) !=
NULL) {
00166 HTHOOKSTRUCT ht;
00167
BOOL bAnsiHook;
00168
00169 ht.pt = *ppt;
00170 ht.hwndHit =
NULL;
00171
00172
xxxCallHook2(pHook, HC_ACTION, 0, (LPARAM)&ht, &bAnsiHook);
00173
00174
if (ht.hwndHit !=
NULL) {
00175
00176 pwnd =
HMValidateHandle(ht.hwndHit, TYPE_WINDOW);
00177
00178
if (pwnd !=
NULL) {
00179 ppt->x = ht.pt.x;
00180 ppt->y = ht.pt.y;
00181 }
00182 }
00183 }
00184
return pwnd;
00185 }
00186
00187
#endif // REDIRECTION
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 PWND SpeedHitTest(
00199
PWND pwndParent,
00200 POINT pt)
00201 {
00202
PWND pwndT;
00203
PWND pwnd;
00204
00205
if (pwndParent ==
NULL)
00206
return NULL;
00207
00208
for (pwnd = pwndParent->
spwndChild; pwnd !=
NULL; pwnd = pwnd->
spwndNext) {
00209
00210
00211
00212
00213
if (!
TestWF(pwnd,
WFVISIBLE))
00214
continue;
00215
00216
00217
00218
00219
if (!
PtInRect((LPRECT)&pwnd->
rcWindow, pt)) {
00220
continue;
00221 }
00222
00223
00224
00225
00226
if (pwnd->
hrgnClip !=
NULL) {
00227
if (!GrePtInRegion(pwnd->
hrgnClip, pt.x, pt.y))
00228
continue;
00229 }
00230
00231
00232
00233
00234
if (
TestWF(pwnd,
WEFLAYERED)) {
00235
if (!
LayerHitTest(pwnd, pt))
00236
continue;
00237 }
00238
00239
#ifdef REDIRECTION
00240
if (
TestWF(pwnd, WEFREDIRECTED)) {
00241
continue;
00242 }
00243
#endif // REDIRECTION
00244
00245
00246
00247
00248
if ((pwnd->
spwndChild !=
NULL) &&
00249
PtInRect((LPRECT)&pwnd->
rcClient, pt)) {
00250
00251 pwndT =
SpeedHitTest(pwnd, pt);
00252
if (pwndT !=
NULL)
00253
return pwndT;
00254 }
00255
00256
return pwnd;
00257 }
00258
00259
return pwndParent;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 HWND
xxxWindowHitTest(
00275
PWND pwnd,
00276 POINT pt,
00277
int *piPos,
00278 DWORD dwHitTestFlags)
00279 {
00280 HWND hwndT;
00281
TL tlpwnd;
00282
00283
CheckLock(pwnd);
00284
00285 hwndT =
NULL;
00286
ThreadLockNever(&tlpwnd);
00287
while (pwnd !=
NULL) {
00288
ThreadLockExchangeAlways(pwnd, &tlpwnd);
00289 hwndT =
xxxWindowHitTest2(pwnd, pt, piPos, dwHitTestFlags);
00290
if (hwndT !=
NULL)
00291
break;
00292
00293 pwnd = pwnd->
spwndNext;
00294 }
00295
00296
ThreadUnlock(&tlpwnd);
00297
return hwndT;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 HWND
xxxWindowHitTest2(
00316
PWND pwnd,
00317 POINT pt,
00318
int *piPos,
00319 DWORD dwHitTestFlags)
00320 {
00321
int ht = HTERROR, htGrip=HTBOTTOMRIGHT;
00322 HWND hwndT;
00323
TL tlpwndChild;
00324
00325
CheckLock(pwnd);
00326
00327
00328
00329
00330
if (pwnd ==
NULL)
00331
return NULL;
00332
00333
00334
00335
00336
if (!
TestWF(pwnd,
WFVISIBLE))
00337
return NULL;
00338
00339
00340
00341
00342
if (!
PtInRect((LPRECT)&pwnd->
rcWindow, pt)) {
00343
return NULL;
00344 }
00345
00346
if (pwnd->
hrgnClip !=
NULL) {
00347
if (!GrePtInRegion(pwnd->
hrgnClip, pt.x, pt.y))
00348
return(
NULL);
00349 }
00350
00351
if (
TestWF(pwnd,
WEFLAYERED)) {
00352
if (!
LayerHitTest(pwnd, pt))
00353
return NULL;
00354 }
00355
00356
#ifdef REDIRECTION
00357
00358
00359
00360
00361
if (
TestWF(pwnd, WEFREDIRECTED) &&
PpiCurrent() !=
GETPTI(pwnd)->ppi) {
00362
return NULL;
00363 }
00364
#endif // REDIRECTION
00365
00366
00367
00368
00369
if (
TestWF(pwnd,
WFDISABLED) && (dwHitTestFlags &
WHT_IGNOREDISABLED)) {
00370
if (
TestwndChild(pwnd)) {
00371
return NULL;
00372 }
else {
00373 ht = HTERROR;
00374
goto Exit;
00375 }
00376 }
00377
00378
#ifdef SYSMODALWINDOWS
00379
00380
00381
00382
00383
00384
if (!
CheckPwndFilter(pwnd, gspwndSysModal)) {
00385 pwnd = gspwndSysModal;
00386
00387
00388
00389
00390 ht = HTCLIENT;
00391
goto Exit;
00392 }
00393
#endif
00394
00395
00396
00397
00398
if (!
TestWF(pwnd,
WFMINIMIZED)) {
00399
00400
00401
00402
if (
PtInRect((LPRECT)&pwnd->
rcClient, pt)) {
00403
00404
00405
00406
ThreadLock(pwnd->
spwndChild, &tlpwndChild);
00407 hwndT =
xxxWindowHitTest(pwnd->
spwndChild,
00408 pt,
00409 piPos,
00410 dwHitTestFlags);
00411
00412
ThreadUnlock(&tlpwndChild);
00413
if (hwndT !=
NULL)
00414
return hwndT;
00415 }
00416
00417 }
00418
00419
00420
00421
00422
if (
GETPTI(pwnd) !=
PtiCurrent()) {
00423 ht = HTCLIENT;
00424
goto Exit;
00425 }
00426
00427
00428
00429
00430 ht = (
int)
xxxSendMessage(pwnd, WM_NCHITTEST, 0, MAKELONG(pt.x, pt.y));
00431
00432
00433
00434
00435
if (ht == HTTRANSPARENT) {
00436
return NULL;
00437 }
00438
00439 Exit:
00440
00441
00442
00443
00444
if (piPos) {
00445 *piPos = ht;
00446 }
00447
00448
00449
00450
00451
00452
00453
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
00454 htGrip = HTBOTTOMLEFT;
00455 }
00456
00457
00458
00459
00460
00461
if ((ht == htGrip) && !
TestWF(pwnd,
WFSIZEBOX)) {
00462
00463
PWND pwndT;
00464
00465
00466
00467
00468 pwnd = (pwndT =
SizeBoxHwnd(pwnd)) ? pwndT : pwnd;
00469 }
00470
00471
return HWq(pwnd);
00472 }