BOOL IsVisible( PWND pwnd) { PWND pwndT; for (pwndT = pwnd; pwndT; pwndT = REBASEPWND(pwndT, spwndParent)) { /* * Invisible windows are always invisible */ if (!TestWF(pwndT, WFVISIBLE)) return FALSE; if (TestWF(pwndT, WFMINIMIZED)) { /* * Children of minimized windows are always invisible. */ if (pwndT != pwnd) return FALSE; } /* * If we're at the desktop, then we don't want to go any further. */ if (GETFNID(pwndT) == FNID_DESKTOP) break; } return TRUE; }
VOID _GetClientRect( PWND pwnd, LPRECT prc) { /* * If this is a 3.1 app, and it's minimized, then we need to return * a rectangle other than the real-client-rect. This is necessary since * there is no client-rect-size in Win4.0. Apps such as PackRat 1.0 * will GPF if returned a empty-rect. */ if (TestWF(pwnd, WFMINIMIZED) && !TestWF(pwnd, WFWIN40COMPAT)) { prc->left = 0; prc->top = 0; prc->right = SYSMETRTL(CXMINIMIZED); prc->bottom = SYSMETRTL(CYMINIMIZED); } else { if (GETFNID(pwnd) != FNID_DESKTOP) { *prc = pwnd->rcClient; OffsetRect(prc, -pwnd->rcClient.left, -pwnd->rcClient.top); } else { /* * For compatibility, return the rect of the primary * monitor for the desktop window. */ prc->left = prc->top = 0; prc->right = SYSMETRTL(CXSCREEN); prc->bottom = SYSMETRTL(CYSCREEN); } } }
/*****************************************************************************\ * * RealChildWindowFromPoint() * * This returns the REAL child window at a point. The problem is that * ChildWindowFromPoint() doesn't deal with HTTRANSPARENT areas of * standard controls. We want to return a child behind a groupbox if it * is in the "clear" area. But we want to return a static field always * even though it too returns HTTRANSPARENT. * \*****************************************************************************/ PWND WINAPI _RealChildWindowFromPoint(PWND pwndParent, POINT pt) { PWND pwndChild; PWND pwndSave; if (pwndParent != PWNDDESKTOP(pwndParent)) { pt.x += pwndParent->rcClient.left; pt.y += pwndParent->rcClient.top; } /* * Is this point even in the parent? */ if (!PtInRect(&pwndParent->rcClient, pt) || (pwndParent->hrgnClip && !GrePtInRegion(pwndParent->hrgnClip, pt.x, pt.y))) { // Nope return NULL; } pwndSave = NULL; /* * Loop through the children. */ for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild = pwndChild->spwndNext) { if (!TestWF(pwndChild, WFVISIBLE)) continue; /* * Is this point in the child's window? */ if (!PtInRect(&pwndChild->rcWindow, pt) || (pwndChild->hrgnClip && !GrePtInRegion(pwndChild->hrgnClip, pt.x, pt.y))) continue; /* * OK, we are in somebody's window. Is this by chance a group box? */ if ((pwndChild->pcls->atomClassName == gpsi->atomSysClass[ICLS_BUTTON]) || (GETFNID(pwndChild) == FNID_BUTTON)) { if (TestWF(pwndChild, BFTYPEMASK) == LOBYTE(BS_GROUPBOX)) { pwndSave = pwndChild; continue; } } return pwndChild; } /* * Did we save a groupbox which turned out to have nothing behind it * at that point? */ if (pwndSave) { return pwndSave; } else { return pwndParent; } }
void GetRealClientRect( PWND pwnd, LPRECT prc, UINT uFlags) { if (GETFNID(pwnd) == FNID_DESKTOP) { *prc = (uFlags & GRC_FULLSCREEN) ? pwnd->rcWindow : gpsi->rcWork; } else { _GetClientRect(pwnd, prc); if (uFlags & GRC_SCROLLS) { if (TestWF(pwnd, WFHPRESENT)) prc->bottom += SYSMET(CYHSCROLL); if (TestWF(pwnd, WFVPRESENT)) prc->right += SYSMET(CXVSCROLL); } } if (uFlags & GRC_MINWNDS) { switch (SYSMET(ARRANGE) & ~ARW_HIDE) { case ARW_TOPLEFT | ARW_RIGHT: case ARW_TOPRIGHT | ARW_LEFT: // // Leave space on top for one row of min windows // prc->top += SYSMET(CYMINSPACING); break; case ARW_TOPLEFT | ARW_DOWN: case ARW_BOTTOMLEFT | ARW_UP: // // Leave space on left for one column of min windows // prc->left += SYSMET(CXMINSPACING); break; case ARW_TOPRIGHT | ARW_DOWN: case ARW_BOTTOMRIGHT | ARW_UP: // // Leave space on right for one column of min windows // prc->right -= SYSMET(CXMINSPACING); break; case ARW_BOTTOMLEFT | ARW_RIGHT: case ARW_BOTTOMRIGHT | ARW_LEFT: // // Leave space on bottom for one row of min windows // prc->bottom -= SYSMET(CYMINSPACING); break; } } }
/***************************************************************************\ * GetMenuPwnd * * This function is used by xxxGetMenuItemRect and xxxMenuItemFromPoint * which expect a pointer to the menu window for popup menus. * In 4.0, apps had to go the extra mile to find the menu window; but this * is bogus since menu windows are an internally thing not directly exposed * to applications. * * 08/19/97 GerardoB Created \***************************************************************************/ PWND GetMenuPwnd (PWND pwnd, PMENU pmenu) { if (TestMF(pmenu, MFISPOPUP)) { if ((pwnd == NULL) || (GETFNID(pwnd) != FNID_MENU)) { PPOPUPMENU ppopup = MNGetPopupFromMenu(pmenu, NULL); if (ppopup != NULL) { UserAssert(ppopup->spmenu == pmenu); pwnd = ppopup->spwndPopupMenu; } } } return pwnd; }
BOOL _IsDescendant( PWND pwndParent, PWND pwndChild) { while (1) { if (pwndParent == pwndChild) return TRUE; if (GETFNID(pwndChild) == FNID_DESKTOP) break; pwndChild = REBASEPWND(pwndChild, spwndParent); } return FALSE; }
/***************************************************************************\ * * _GetListBoxInfo() * * Currently returns back the # of items per column. There is no way to get * or calculate this info any other way in a multicolumn list. * * For now, no structure is returned. If we ever need one more thing, make one. * * Since I have to run on multiple platforms, I can't define a message. * To do so would require that * * I make changes to the thunk table * * I make sure the 32-bit define doesn't collide with some NT new msg * * I use a different value on Win '95 vs Memphis due to additions * * I test apps extensively since many of them pass on bogus valued * messages to the listbox handler which checks to see if they * are in range. In other words, any value I pick is probably * going to flake out MSVC++ 4.0. * * Ergo an API instead. * \***************************************************************************/ DWORD WINAPI _GetListBoxInfo(PWND pwnd) { PCLS pcls; DWORD dwRet = 0; BOOL fOtherProcess; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((pcls->atomClassName != gpsi->atomSysClass[ICLS_LISTBOX]) && (GETFNID(pwnd) != FNID_LISTBOX)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "pwnd %#p is not a listbox", pwnd); return 0; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PLBIV ccxPlbSnap; /* * Snap and probe the pointer to the LBIV, since it is client-side. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); if (ccxPlbSnap->fMultiColumn) { dwRet = ccxPlbSnap->itemsPerColumn; } else { dwRet = ccxPlbSnap->cMac; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { dwRet = 0; } errorexit: if (fOtherProcess) { KeDetachProcess(); } return dwRet; }
DWORD GetContextHelpId( PWND pwnd) { DWORD dwContextId; while (!(dwContextId = (DWORD)_GetProp(pwnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), PROPF_INTERNAL))) { pwnd = (TestwndChild(pwnd) ? REBASEPWND(pwnd, spwndParent) : REBASEPWND(pwnd, spwndOwner)); if (!pwnd || (GETFNID(pwnd) == FNID_DESKTOP)) break; } return dwContextId; }
VOID _GetWindowRect( PWND pwnd, LPRECT prc) { if (GETFNID(pwnd) != FNID_DESKTOP) { *prc = pwnd->rcWindow; } else { /* * For compatibility, return the rect of the primary * monitor for the desktop window. */ prc->left = 0; prc->top = 0; prc->right = SYSMETRTL(CXSCREEN); prc->bottom = SYSMETRTL(CYSCREEN); } }
VOID _ScreenToClient( PWND pwnd, PPOINT ppt) { /* * Client and screen coordinates are the same for the * desktop window. */ if (GETFNID(pwnd) != FNID_DESKTOP) { #ifdef USE_MIRRORING if (TestWF(pwnd, WEFLAYOUTRTL)) { ppt->x = pwnd->rcClient.right - ppt->x; } else #endif { ppt->x -= pwnd->rcClient.left; } ppt->y -= pwnd->rcClient.top; } }
PWND SizeBoxHwnd( PWND pwnd) { int xbrChild = pwnd->rcWindow.right; int ybrChild = pwnd->rcWindow.bottom; while (GETFNID(pwnd) != FNID_DESKTOP) { if (TestWF(pwnd, WFSIZEBOX)) { // First sizeable parent found int xbrParent; int ybrParent; if (TestWF(pwnd, WFMAXIMIZED)) return(NULL); xbrParent = pwnd->rcClient.right; ybrParent = pwnd->rcClient.bottom; /* If the sizebox dude is within an EDGE of the client's bottom * right corner, let this succeed. That way people who draw * their own sunken clients will be happy. */ if ((xbrChild + SYSMET(CXEDGE) < xbrParent) || (ybrChild + SYSMET(CYEDGE) < ybrParent)) { // // Child's bottom, right corner of SIZEBOX isn't close enough // to bottom right of parent's client. // return(NULL); } return(pwnd); } if (!TestWF(pwnd, WFCHILD) || TestWF(pwnd, WFCPRESENT)) break; pwnd = REBASEPWND(pwnd, spwndParent); } return(NULL); }
BOOL _IsWindowVisible( PWND pwnd) { /* * Check if this is the iconic window being moved around with a mouse * If so, return a TRUE, though, strictly speaking, it is hidden. * This helps the Tracer guys from going crazy! * Fix for Bug #57 -- SANKAR -- 08-08-89 -- */ if (pwnd == NULL) return TRUE; for (;;) { if (!TestWF(pwnd, WFVISIBLE)) return FALSE; if (GETFNID(pwnd) == FNID_DESKTOP) break; pwnd = REBASEPWND(pwnd, spwndParent); } return TRUE; }
BOOL DoPaint( PWND pwndFilter, LPMSG lpMsg) { PWND pwnd; PWND pwndT; PTHREADINFO ptiCurrent = PtiCurrent(); #if 0 // CHRISWIL: WIN95 SPECIFIC /* * If there is a system modal up and it is attached to another task, * DON'T do paints. We don't want to return a message for a window in * another task! */ if (hwndSysModal && (hwndSysModal->hq != hqCurrent)) { /* * Poke this guy so he wakes up at some point in the future, * otherwise he may never wake up to realize he should paint. * Causes hangs - e.g. Photoshop installation program * PostThreadMessage32(Lpq(hqCurrent)->idThread, WM_NULL, 0, 0, 0); */ return FALSE; } #endif /* * If this is a system thread, then walk the windowstation desktop-list * to find the window which needs painting. For other threads, we * reference off the thread-desktop. */ if (ptiCurrent->TIF_flags & TIF_SYSTEMTHREAD) { PWINDOWSTATION pwinsta; PDESKTOP pdesk; if ((pwinsta = ptiCurrent->pwinsta) == NULL) { RIPMSG0(RIP_ERROR, "DoPaint: SYSTEMTHREAD does not have (pwinsta)"); return FALSE; } pwnd = NULL; for(pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) { if (pwnd = InternalDoPaint(pdesk->pDeskInfo->spwnd, ptiCurrent)) break; } } else { pwnd = InternalDoPaint(ptiCurrent->rpdesk->pDeskInfo->spwnd, ptiCurrent); } if (pwnd != NULL) { if (!CheckPwndFilter(pwnd, pwndFilter)) return FALSE; /* * We're returning a WM_PAINT message, so clear WFINTERNALPAINT so * it won't get sent again later. */ if (TestWF(pwnd, WFINTERNALPAINT)) { ClrWF(pwnd, WFINTERNALPAINT); /* * If there is no update region, then no more paint for this * window. */ if (pwnd->hrgnUpdate == NULL) DecPaintCount(pwnd); } /* * Set the STARTPAINT so that any other calls to BeginPaint while * painting is begin performed, will prevent painting on those * windows. * * Clear the UPDATEDIRTY since some apps (DBFast) don't call * GetUpdateRect, BeginPaint/EndPaint. */ ClrWF(pwnd, WFSTARTPAINT); ClrWF(pwnd, WFUPDATEDIRTY); /* * If we get an invalidate between now and the time the app calls * BeginPaint() and the windows parent is not CLIPCHILDREN, then * the parent will paint in the wrong order. So we are going to * cause the child to paint again. Look in beginpaint and internal * invalidate for other parts of this fix. * * Set a flag to signify that we are in the bad zone. * * Must go up the parent links to make sure all parents have * WFCLIPCHILDREN set otherwise set the WFWMPAINTSENT flag. * This is to fix Excel spreadsheet and fulldrag. The speadsheet * parent window (class XLDESK) has WFCLIPCHILDREN set but it's * parent (class XLMAIN) doesn't. So the main window erases the * background after the child window paints. * * JOHANNEC : 27-Jul-1994 */ /* * NT Bug 400167: As we walk up the tree, we need to stop short of * desktop windows and mother desktop windows. We can't do a test * for WFCLIPCHILDREN on the mother desktop window's parent because * it doesn't exist. This means that no desktop window will get * WFWMPAINTSENT set, but the message window will be able to get * WFWMPAINTSENT set. */ pwndT = pwnd; while (pwndT && (GETFNID(pwndT) != FNID_DESKTOP)) { if (!TestWF(pwndT->spwndParent, WFCLIPCHILDREN)) { SetWF(pwnd, WFWMPAINTSENT); break; } pwndT = pwndT->spwndParent; } /* * If the top level "tiled" owner/parent of this window is iconed, * send a WM_PAINTICON rather than a WM_PAINT. The wParam * is TRUE if this is the tiled window and FALSE if it is a * child/owned popup of the minimized window. * * BACKWARD COMPATIBILITY HACK * * 3.0 sent WM_PAINTICON with wParam == TRUE for no apparent * reason. Lotus Notes 2.1 depends on this for some reason * to properly change its icon when new mail arrives. */ if (!TestWF(pwnd, WFWIN40COMPAT) && TestWF(pwnd, WFMINIMIZED) && (pwnd->pcls->spicn != NULL)) { StoreMessage(lpMsg, pwnd, WM_PAINTICON, (DWORD)TRUE, 0L, 0L); } else { StoreMessage(lpMsg, pwnd, WM_PAINT, 0, 0L, 0L); } return TRUE; } return FALSE; }
WORD _SetWindowWord( PWND pwnd, int index, WORD value) { WORD wOld; /* * Don't allow setting of words belonging to a system thread if the caller * is not a system thread. Same goes for winlogon. */ if (!FCallerOk(pwnd)) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return 0; } /* * Applications can not set a WORD into a dialog Proc or any of the * non-public reserved bytes in DLGWINDOWEXTRA (usersrv stores pointers * theres) */ if (TestWF(pwnd, WFDIALOGWINDOW)) { if (((index >= DWLP_DLGPROC) && (index < DWLP_MSGRESULT)) || ((index > DWLP_USER+sizeof(LONG_PTR)-sizeof(WORD)) && (index < DLGWINDOWEXTRA))) { RIPERR3(ERROR_INVALID_INDEX, RIP_WARNING, "SetWindowWord: Trying to set WORD of a windowproc pwnd=(%#p) index=(%ld) fnid (%lX)", pwnd, index, (DWORD)pwnd->fnid); return 0; } else { /* * If this is really a dialog and not some other server class * where usersrv has stored some data (Windows Compuserve - * wincim - does this) then store the data now that we have * verified the index limits. */ if (GETFNID(pwnd) == FNID_DIALOG) goto DoSetWord; } } if (index == GWLP_USERDATA) { wOld = (WORD)pwnd->dwUserData; pwnd->dwUserData = MAKELONG(value, HIWORD(pwnd->dwUserData)); return wOld; } // fix for RedShift, they call SetWindowWord // tn play with the low word of the style dword if (index == GWL_STYLE) { wOld = (WORD)pwnd->style; pwnd->style = MAKELONG(value, HIWORD(pwnd->style)); return wOld; } if (GETFNID(pwnd) != 0) { if (index >= 0 && (index < (int)(CBFNID(pwnd->fnid)-sizeof(WND)))) { switch (GETFNID(pwnd)) { case FNID_MDICLIENT: if (index == 0) break; goto DoDefault; case FNID_BUTTON: /* * CorelDraw, Direct Access 1.0 and WordPerfect 6.0 do a * get/set on the first button window word. Allow this * for compatibility. */ if (index == 0) { /* * Since we now use a lookaside buffer for the control's * private data, we need to indirect into this structure. */ PBUTN pbutn = ((PBUTNWND)pwnd)->pbutn; if (!pbutn || (LONG_PTR)pbutn == (LONG_PTR)-1) { return 0; } else { try { wOld = (WORD)ProbeAndReadUlong(&pbutn->buttonState); pbutn->buttonState = value; } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { wOld = 0; } return wOld; } } goto DoDefault; default: DoDefault: RIPERR3(ERROR_INVALID_INDEX, RIP_WARNING, "SetWindowWord: Trying to set private server data pwnd=(%#p) index=(%ld) fnid (%lX)", pwnd, index, (DWORD)pwnd->fnid); return 0; break; } } }
/***************************************************************************\ * * _GetComboBoxInfo() * * This returns combobox information for either a combo or its dropdown * list. * \***************************************************************************/ BOOL WINAPI _GetComboBoxInfo(PWND pwnd, PCOMBOBOXINFO pcbi) { PCLS pcls; COMBOBOXINFO cbi = { sizeof cbi, }; BOOL fOtherProcess; BOOL bRetval = FALSE; WORD wWindowType = 0; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((GETFNID(pwnd) == FNID_COMBOBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX])) { wWindowType = FNID_COMBOBOX; } else if ((GETFNID(pwnd) == FNID_COMBOLISTBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOLISTBOX])) { wWindowType = FNID_COMBOLISTBOX; } else { RIPERR1(ERROR_WINDOW_NOT_COMBOBOX, RIP_WARNING, "pwnd %#p not a combobox or dropdown", pwnd); return FALSE; } /* * Validate combo structure */ if (pcbi->cbSize != sizeof(COMBOBOXINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "COMBOBOXINFO.cbSize %d is wrong", pcbi->cbSize); return FALSE; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PCBOX ccxPcboxSnap; PWND ccxPwndSnap; HWND ccxHwndSnap; /* * Snap and probe the CBOX structure, since it is client side. */ if (wWindowType == FNID_COMBOBOX) { ccxPcboxSnap = ((PCOMBOWND)pwnd)->pcbox; } else { PLBIV ccxPlbSnap; /* * If this is a listbox, we must snap and probe the LBIV structure * in order to get to the CBOX structure. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); ccxPcboxSnap = ccxPlbSnap->pcbox; } if (!ccxPcboxSnap) { goto errorexit; } ProbeForRead(ccxPcboxSnap, sizeof(CBOX), DATAALIGN); /* * Get the combo information now */ /* * Snap and probe the client side pointer to the Combo window */ ccxPwndSnap = ccxPcboxSnap->spwnd; ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndCombo = HWCCX(ccxPwndSnap); /* * Snap & probe the client side pointer to the Edit window. * To compare spwndEdit and pwnd, we should compare handles * since spwndEdit is a client-side address and pwnd is a * kernel-mode address, */ ccxPwndSnap = ccxPcboxSnap->spwndEdit; /* * If combobox is not fully initialized and spwndEdit is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); ccxHwndSnap = HWCCX(ccxPwndSnap); if (ccxHwndSnap == HW(pwnd)) { /* * ComboBox doesn't have Edit control. */ cbi.hwndItem = NULL; } else { cbi.hwndItem = HWCCX(ccxPwndSnap); } /* * Snap and probe the client side pointer to the List window */ ccxPwndSnap = ccxPcboxSnap->spwndList; /* * If combobox is not fully initialized and spwndList is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndList = HWCCX(ccxPwndSnap); /* * Snap the rest of the combo information. * We don't need to probe any of these, since there are no more indirections. */ cbi.rcItem = ccxPcboxSnap->editrc; cbi.rcButton = ccxPcboxSnap->buttonrc; /* * Button state */ cbi.stateButton = 0; if (ccxPcboxSnap->CBoxStyle == CBS_SIMPLE) { cbi.stateButton |= STATE_SYSTEM_INVISIBLE; } if (ccxPcboxSnap->fButtonPressed) { cbi.stateButton |= STATE_SYSTEM_PRESSED; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { goto errorexit; } *pcbi = cbi; bRetval = TRUE; errorexit: if (fOtherProcess) { KeDetachProcess(); } return bRetval; }
WORD _GetWindowWord( PWND pwnd, int index) { if (GETFNID(pwnd) != 0) { if ((index >= 0) && (index < (int)(CBFNID(pwnd->fnid)-sizeof(WND)))) { switch (GETFNID(pwnd)) { case FNID_MDICLIENT: if (index == 0) break; goto DoDefault; case FNID_BUTTON: /* * CorelDraw does a get/set on the first button window word. * Allow it to. */ if (index == 0) { /* * Since we now use a lookaside buffer for the control's * private data, we need to indirect into this structure. */ PBUTN pbutn = ((PBUTNWND)pwnd)->pbutn; if (!pbutn || (LONG)pbutn == (LONG)-1) { return 0; } else { return (WORD)(pbutn->buttonState); } } goto DoDefault; case FNID_DIALOG: if (index == DWL_USER) return LOWORD(((PDIALOG)pwnd)->unused); if (index == DWL_USER+2) return HIWORD(((PDIALOG)pwnd)->unused); goto DoDefault; default: DoDefault: RIPERR3(ERROR_INVALID_INDEX, RIP_WARNING, "GetWindowWord: Trying to read private server data pwnd=(%lX) index=(%ld) fnid=(%lX)", pwnd, index, (DWORD)pwnd->fnid); return 0; break; } } } if (index == GWL_USERDATA) return (WORD)pwnd->dwUserData; if ((index < 0) || (index + (int)sizeof(WORD) > pwnd->cbwndExtra)) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return 0; } else { return *((WORD UNALIGNED *)((BYTE *)(pwnd + 1) + index)); } }
PWND _GetWindow( PWND pwnd, UINT cmd) { PWND pwndT; BOOL fRebase = FALSE; /* * If this is a desktop window, return NULL for sibling or * parent information. */ if (GETFNID(pwnd) == FNID_DESKTOP) { switch (cmd) { case GW_CHILD: break; default: return NULL; break; } } /* * Rebase the returned window at the end of the routine * to avoid multiple test for pwndT == NULL. */ pwndT = NULL; switch (cmd) { case GW_HWNDNEXT: pwndT = pwnd->spwndNext; fRebase = TRUE; break; case GW_HWNDFIRST: if (pwnd->spwndParent) { pwndT = REBASEPWND(pwnd, spwndParent); pwndT = REBASEPWND(pwndT, spwndChild); if (GetAppCompatFlags(NULL) & GACF_IGNORETOPMOST) { while (pwndT != NULL) { if (!TestWF(pwndT, WEFTOPMOST)) break; pwndT = REBASEPWND(pwndT, spwndNext); } } } break; case GW_HWNDLAST: pwndT = GetPrevPwnd(pwnd, NULL); break; case GW_HWNDPREV: pwndT = GetPrevPwnd(pwnd, pwnd); break; case GW_OWNER: pwndT = pwnd->spwndOwner; fRebase = TRUE; break; case GW_CHILD: pwndT = pwnd->spwndChild; fRebase = TRUE; break; #if !defined(_USERK_) case GW_ENABLEDPOPUP: pwndT = (PWND)NtUserCallHwnd(PtoHq(pwnd), SFI_DWP_GETENABLEDPOPUP); fRebase = TRUE; break; #endif default: RIPERR0(ERROR_INVALID_GW_COMMAND, RIP_VERBOSE, ""); return NULL; } if (pwndT != NULL && fRebase) pwndT = REBASEPTR(pwnd, pwndT); return pwndT; }
BOOL FIsParentDude(PWND pwnd) { return(TestWF(pwnd, WEFCONTROLPARENT) || TestWF(pwnd, WFDIALOGWINDOW) || ((GETFNID(pwnd) == FNID_BUTTON) && (TestWF(pwnd, BFTYPEMASK) == BS_GROUPBOX))); }