test: winwhere.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# winwhere.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Functions

__inline BOOL | LayerHitTest (PWND pwnd, POINT pt)
PWND | _ChildWindowFromPointEx (PWND pwnd, POINT pt, UINT uFlags)
PWND | xxxWindowFromPoint (POINT pt)
PWND | SpeedHitTest (PWND pwndParent, POINT pt)
HWND | xxxWindowHitTest (PWND pwnd, POINT pt, int *piPos, DWORD dwHitTestFlags)
HWND | xxxWindowHitTest2 (PWND pwnd, POINT pt, int *piPos, DWORD dwHitTestFlags)

## Function Documentation

PWND _ChildWindowFromPointEx | ( | PWND | pwnd,
|  | POINT | pt,
|  | UINT | uFlags
| ) |

Definition at line 47 of file winwhere.c.

References tagWND::hrgnClip, LayerHitTest(), NULL, PtInRect(), PWNDDESKTOP, tagWND::rcClient, tagWND::rcWindow, tagWND::spwndChild, tagWND::spwndNext, TestWF, WEFLAYERED, WEFTRANSPARENT, WFDISABLED, and WFVISIBLE.

Referenced by NtUserChildWindowFromPointEx(), and xxxQueryDropObject().

    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     // _ClientToScreen(pwndParent, (LPPOINT)&pt);
    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          * Enumerate the children, skipping disabled and invisible ones
    00082          * if so desired.  Still doesn't work for WS_EX_TRANSPARENT windows.
    00083          */
    00084         for (pwndChild = pwnd->spwndChild;
    00085                  pwndChild;
    00086                  pwndChild = pwndChild->spwndNext) {
    00087
    00088             /*
    00089              * Skip windows as desired.
    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 }

__inline BOOL LayerHitTest | ( | PWND | pwnd,
|  | POINT | pt
| ) |

Definition at line 21 of file winwhere.c.

References ASSERT, BOOL, FALSE, gpDispInfo, tagDISPLAYINFO::hDev, PtoHq, TestWF, TRUE, WEFLAYERED, and WEFTRANSPARENT.

Referenced by _ChildWindowFromPointEx(), SpeedHitTest(), and xxxWindowHitTest2().

    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 }

PWND SpeedHitTest | ( | PWND | pwndParent,
|  | POINT | pt
| ) |

Definition at line 198 of file winwhere.c.

References tagWND::hrgnClip, LayerHitTest(), NULL, PtInRect(), tagWND::rcClient, tagWND::rcWindow, tagWND::spwndChild, tagWND::spwndNext, TestWF, WEFLAYERED, and WFVISIBLE.

Referenced by xxxButtonEvent(), and zzzSetFMouseMoved().

    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          * Are we looking at an hidden window?
    00212          */
    00213         if (!TestWF(pwnd, WFVISIBLE))
    00214             continue;
    00215
    00216         /*
    00217          * Are we barking up the wrong tree?
    00218          */
    00219         if (!PtInRect((LPRECT)&pwnd->rcWindow, pt)) {
    00220             continue;
    00221         }
    00222
    00223         /*
    00224          * Check to see if in window region (if it has one)
    00225          */
    00226         if (pwnd->hrgnClip != NULL) {
    00227             if (!GrePtInRegion(pwnd->hrgnClip, pt.x, pt.y))
    00228                 continue;
    00229         }
    00230
    00231         /*
    00232          * Is this a sprite?
    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          * Children?
    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 }

PWND xxxWindowFromPoint | ( | POINT | pt | ) |

Definition at line 128 of file winwhere.c.

References _GetDesktopWindow(), NULL, RevalidateHwnd, ThreadLock, ThreadUnlock, WHT_IGNOREDISABLED, and xxxWindowHitTest2().

Referenced by NtUserWindowFromPoint().

    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 }

HWND xxxWindowHitTest | ( | PWND | pwnd,
|  | POINT | pt,
|  | int * | piPos,
|  | DWORD | dwHitTestFlags
| ) |

Definition at line 274 of file winwhere.c.

References CheckLock, NULL, tagWND::spwndNext, ThreadLockExchangeAlways(), ThreadLockNever, ThreadUnlock, and xxxWindowHitTest2().

Referenced by xxxHelpLoop(), xxxScanSysQueue(), and xxxWindowHitTest2().

    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 }

HWND xxxWindowHitTest2 | ( | PWND | pwnd,
|  | POINT | pt,
|  | int * | piPos,
|  | DWORD | dwHitTestFlags
| ) |

Definition at line 315 of file winwhere.c.

References CheckLock, CheckPwndFilter(), GETPTI, tagWND::hrgnClip, HWq, LayerHitTest(), NULL, PpiCurrent, PtiCurrent, PtInRect(), tagWND::rcClient, tagWND::rcWindow, SizeBoxHwnd(), tagWND::spwndChild, TestWF, TestwndChild, ThreadLock, ThreadUnlock, WEFLAYERED, WFDISABLED, WFMINIMIZED, WFSIZEBOX, WFVISIBLE, WHT_IGNOREDISABLED, xxxSendMessage(), and xxxWindowHitTest().

Referenced by xxxWindowFromPoint(), and xxxWindowHitTest().

    00320 {
    00321     int  ht = HTERROR, htGrip=HTBOTTOMRIGHT;
    00322     HWND hwndT;
    00323     TL   tlpwndChild;
    00324
    00325     CheckLock(pwnd);
    00326
    00327     /*
    00328      * Are we at the bottom of the window chain?
    00329      */
    00330     if (pwnd == NULL)
    00331         return NULL;
    00332
    00333     /*
    00334      * Are we looking at an hidden window?
    00335      */
    00336     if (!TestWF(pwnd, WFVISIBLE))
    00337         return NULL;
    00338
    00339     /*
    00340      * Are we barking up the wrong tree?
    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      * If this is called when the layered window is actually trying
    00359      * to process the message then let it see the hit test
    00360      */
    00361     if (TestWF(pwnd, WEFREDIRECTED) && PpiCurrent() != GETPTI(pwnd)->ppi) {
    00362         return NULL;
    00363     }
    00364 #endif // REDIRECTION
    00365
    00366     /*
    00367      * Are we looking at an disabled window?
    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      * If SysModal window present and we're not in it, return an error.
    00381      * Be sure to assign the point to the SysModal window, so the message
    00382      * will be sure to be removed from the queue.
    00383      */
    00384     if (!CheckPwndFilter(pwnd, gspwndSysModal)) {
    00385         pwnd = gspwndSysModal;
    00386
    00387         /*
    00388          * Fix notorious stack overflow bug (some WINABLE fix from Memphis)
    00389          */
    00390         ht = HTCLIENT;
    00391         goto Exit;
    00392     }
    00393 #endif
    00394
    00395     /*
    00396      * Are we on a minimized window?
    00397      */
    00398     if (!TestWF(pwnd, WFMINIMIZED)) {
    00399         /*
    00400          * Are we in the window's client area?
    00401          */
    00402         if (PtInRect((LPRECT)&pwnd->rcClient, pt)) {
    00403             /*
    00404              * Recurse through the children.
    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      * If window not in same task, don't send WM_NCHITTEST.
    00421      */
    00422     if (GETPTI(pwnd) != PtiCurrent()) {
    00423         ht = HTCLIENT;
    00424         goto Exit;
    00425     }
    00426
    00427     /*
    00428      * Send the message.
    00429      */
    00430     ht = (int)xxxSendMessage(pwnd, WM_NCHITTEST, 0, MAKELONG(pt.x, pt.y));
    00431
    00432     /*
    00433      * If window is transparent keep enumerating.
    00434      */
    00435     if (ht == HTTRANSPARENT) {
    00436         return NULL;
    00437     }
    00438
    00439 Exit:
    00440
    00441     /*
    00442      * Set wndpos accordingly.
    00443      */
    00444     if (piPos) {
    00445         *piPos = ht;
    00446     }
    00447
    00448     /*
    00449      * If this is a RTL mirrored window, then the grip is at
    00450      * HTBOTTOMLEFT (in terms of screen coordinates since they are
    00451      * not RTL mirrored).
    00452      */
    00453     if (TestWF(pwnd, WEFLAYOUTRTL)) {
    00454         htGrip = HTBOTTOMLEFT;
    00455     }
    00456
    00457     /*
    00458      * if the click is in the sizebox of the window and this window itself is
    00459      * not sizable, return the window that will be sized by this sizebox
    00460      */
    00461     if ((ht == htGrip) && !TestWF(pwnd, WFSIZEBOX)) {
    00462
    00463         PWND  pwndT;
    00464          /*
    00465           * SizeBoxHwnd() can return NULL!  We don't want to act like this
    00466           * is transparent if the sizebox isn't a grip
    00467           */
    00468          pwnd = (pwndT = SizeBoxHwnd(pwnd)) ? pwndT : pwnd;
    00469     }
    00470
    00471     return HWq(pwnd);
    00472 }