void xxxMNRecomputeBarIfNeeded( PWND pwndNotify, PMENU pMenu) { int cxFrame; int cyFrame; UserAssert(!TestMF(pMenu, MFISPOPUP)); CheckLock(pwndNotify); CheckLock(pMenu); if (!TestMF(pMenu, MFSYSMENU) && ((pMenu->spwndNotify != pwndNotify) || !pMenu->cxMenu || !pMenu->cyMenu)) { int cBorders; cBorders = GetWindowBorders(pwndNotify->style, pwndNotify->ExStyle, TRUE, FALSE); cxFrame = cBorders * SYSMET(CXBORDER); cyFrame = cBorders * SYSMET(CYBORDER); cyFrame += GetCaptionHeight(pwndNotify); // The width passed in this call was larger by cxFrame; // Fix for Bug #11466 - Fixed by SANKAR - 01/06/92 -- xxxMenuBarCompute(pMenu, pwndNotify, cyFrame, cxFrame, (pwndNotify->rcWindow.right - pwndNotify->rcWindow.left) - cxFrame * 2); } }
void MNPositionSysMenu( PWND pwnd, PMENU pmenusys) { RECT rc; PITEM pItem; if (pmenusys == NULL) { RIPERR0(ERROR_INVALID_HANDLE, RIP_WARNING, "Invalid menu handle pmenusys (NULL) to MNPositionSysMenu"); return; } /* * Setup the SysMenu hit rectangle. */ rc.top = rc.left = 0; if (TestWF(pwnd, WEFTOOLWINDOW)) { rc.right = SYSMET(CXSMSIZE); rc.bottom = SYSMET(CYSMSIZE); } else { rc.right = SYSMET(CXSIZE); rc.bottom = SYSMET(CYSIZE); } if (!TestWF(pwnd, WFMINIMIZED)) { int cBorders; cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); OffsetRect(&rc, cBorders*SYSMET(CXBORDER), cBorders*SYSMET(CYBORDER)); } /* * Offset the System popup menu. */ Lock(&pmenusys->spwndNotify, pwnd); if (!TestMF(pmenusys, MF_POPUP) && (pmenusys->cItems > 0)) { pItem = pmenusys->rgItems; if (pItem) { pItem->yItem = rc.top; pItem->xItem = rc.left; pItem->cyItem = rc.bottom - rc.top; pItem->cxItem = rc.right - rc.left; } } else // BOGUS -- MF_POPUP should never be set on a MENU -- only a MENU ITEM UserAssert(FALSE); }
int FindNCHit( PWND pwnd, LONG lPt) { POINT pt; RECT rcWindow; RECT rcClient; RECT rcClientAdj; int cBorders; int dxButton; pt.x = LOWORD(lPt); pt.y = HIWORD(lPt); if (!PtInRect(&pwnd->rcWindow, pt)) return HTNOWHERE; if (TestWF(pwnd, WFMINIMIZED)) { CopyInflateRect(&rcWindow, &pwnd->rcWindow, -(SYSMET(CXFIXEDFRAME) + SYSMET(CXBORDER)), -(SYSMET(CYFIXEDFRAME) + SYSMET(CYBORDER))); if (!PtInRect(&rcWindow, pt)) return HTCAPTION; goto CaptionHit; } // Get client rectangle rcClient = pwnd->rcClient; if (PtInRect(&rcClient, pt)) return HTCLIENT; // Are we in "pseudo" client, i.e. the client & scrollbars & border if (TestWF(pwnd, WEFCLIENTEDGE)) CopyInflateRect(&rcClientAdj, &rcClient, SYSMET(CXEDGE), SYSMET(CYEDGE)); else rcClientAdj = rcClient; if (TestWF(pwnd, WFVPRESENT)) rcClientAdj.right += SYSMET(CXVSCROLL); if (TestWF(pwnd, WFHPRESENT)) rcClientAdj.bottom += SYSMET(CYHSCROLL); if (!PtInRect(&rcClientAdj, pt)) { // Subtract out window borders cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); CopyInflateRect(&rcWindow, &pwnd->rcWindow, -cBorders*SYSMET(CXBORDER), -cBorders*SYSMET(CYBORDER)); // Are we on the border? if (!PtInRect(&rcWindow, pt)) { // On a sizing border? if (!TestWF(pwnd, WFSIZEBOX)) { // // Old compatibility thing: For 3.x windows that just had // a border, we returned HTNOWHERE, believe it or not, // because our hit-testing code was so brain dead. // if (!TestWF(pwnd, WFWIN40COMPAT) && !TestWF(pwnd, WFDLGFRAME) && !TestWF(pwnd, WEFDLGMODALFRAME)) { return(HTNOWHERE); } else { return(HTBORDER); // We are on a dlg frame. } } else { int ht; // // Note this improvement. The HT codes are numbered so that // if you subtract HTSIZEFIRST-1 from them all, they sum up. I.E., // (HTLEFT - HTSIZEFIRST + 1) + (HTTOP - HTSIZEFIRST + 1) == // (HTTOPLEFT - HTSIZEFIRST + 1). // if (TestWF(pwnd, WEFTOOLWINDOW)) InflateRect(&rcWindow, -SYSMET(CXSMSIZE), -SYSMET(CYSMSIZE)); else InflateRect(&rcWindow, -SYSMET(CXSIZE), -SYSMET(CYSIZE)); if (pt.y < rcWindow.top) ht = (HTTOP - HTSIZEFIRST + 1); else if (pt.y >= rcWindow.bottom) ht = (HTBOTTOM - HTSIZEFIRST + 1); else ht = 0; if (pt.x < rcWindow.left) ht += (HTLEFT - HTSIZEFIRST + 1); else if (pt.x >= rcWindow.right) ht += (HTRIGHT - HTSIZEFIRST + 1); return (ht + HTSIZEFIRST - 1); } } // Are we above the client area? if (pt.y < rcClientAdj.top) { // Are we in the caption? if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) { CaptionHit: if (pt.y >= rcWindow.top) { if (TestWF(pwnd, WEFTOOLWINDOW)) { rcWindow.top += SYSMET(CYSMCAPTION); dxButton = SYSMET(CXSMSIZE); } else { rcWindow.top += SYSMET(CYCAPTION); dxButton = SYSMET(CXSIZE); } if ((pt.y >= rcWindow.top) && TestWF(pwnd, WFMPRESENT)) return(HTMENU); if ((pt.x >= rcWindow.left) && (pt.x < rcWindow.right) && (pt.y < rcWindow.top)) { // Are we in the window menu? if (TestWF(pwnd, WFSYSMENU)) { rcWindow.left += dxButton; if (pt.x < rcWindow.left) { if (!_HasCaptionIcon(pwnd)) // iconless windows have no sysmenu hit rect return(HTCAPTION); return(HTSYSMENU); } } else if (TestWF(pwnd, WFWIN40COMPAT)) return(HTCAPTION); // only a close button if window has a system menu // Are we in the close button? rcWindow.right -= dxButton; if (pt.x >= rcWindow.right) return HTCLOSE; if ((pt.x < rcWindow.right) && !TestWF(pwnd, WEFTOOLWINDOW)) { // Are we in the maximize/restore button? if (TestWF(pwnd, (WFMAXBOX | WFMINBOX))) { // Note that sizing buttons are same width for both // big captions and small captions. rcWindow.right -= dxButton; if (pt.x >= rcWindow.right) return HTZOOM; // Are we in the minimize button? rcWindow.right -= dxButton; if (pt.x >= rcWindow.right) return HTREDUCE; } else if (TestWF(pwnd, WEFCONTEXTHELP)) { rcWindow.right -= dxButton; if (pt.x >= rcWindow.right) return HTHELP; } } } } // We're in the caption proper return HTCAPTION; } // // Are we in the menu? // if (TestWF(pwnd, WFMPRESENT)) return HTMENU; } } else { // // NOTE: // We can only be here if we are on the client edge, horz scroll, // sizebox, or vert scroll. Hence, if we are not on the first 3, // we must be on the last one. // // // Are we on the client edge? // if (TestWF(pwnd, WEFCLIENTEDGE)) { InflateRect(&rcClientAdj, -SYSMET(CXEDGE), -SYSMET(CYEDGE)); if (!PtInRect(&rcClientAdj, pt)) return(HTBORDER); } // // Are we on the scrollbars? // if (TestWF(pwnd, WFHPRESENT) && (pt.y >= rcClient.bottom)) { UserAssert(pt.y < rcClientAdj.bottom); if (TestWF(pwnd, WFVPRESENT) && (pt.x >= rcClient.right)) return(SizeBoxHwnd(pwnd) ? HTBOTTOMRIGHT : HTGROWBOX); else return(HTHSCROLL); } else { UserAssert(TestWF(pwnd, WFVPRESENT)); UserAssert(pt.x >= rcClient.right); UserAssert(pt.x < rcClientAdj.right); return(HTVSCROLL); } } // // We give up. // // Win31 returned HTNOWHERE in this case; For compatibility, we will // keep it that way. // return(HTNOWHERE); }
/* * Modal loop for when the user has selected the help icon from the titlebar * */ VOID xxxHelpLoop(PWND pwnd) { HWND hwndChild; PWND pwndChild; PWND pwndControl; MSG msg; RECT rc; int cBorders; PTHREADINFO ptiCurrent = PtiCurrent(); DLGENUMDATA DlgEnumData; TL tlpwndChild; CheckLock(pwnd); UserAssert(IsWinEventNotifyDeferredOK()); if (FWINABLE()) { xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPSTART, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0); } zzzSetCursor(SYSCUR(HELP)); xxxCapture(ptiCurrent, pwnd, SCREEN_CAPTURE); cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); CopyInflateRect(&rc, &pwnd->rcWindow, -cBorders * SYSMET(CXBORDER), -cBorders * SYSMET(CYBORDER)); while (ptiCurrent->pq->spwndCapture == pwnd) { if (!xxxPeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_NOREMOVE)) { xxxWaitMessage(); continue; } if (msg.message == WM_NCLBUTTONDOWN) { break; } else if (msg.message == WM_LBUTTONDOWN) { /* * If user clicked outside of window client, bail out now. */ if (!PtInRect(&rc, msg.pt)) break; /* * WindowHitTest() won't return a static control's handle */ hwndChild = xxxWindowHitTest(pwnd, msg.pt, NULL, 0); pwndChild = ValidateHwnd( hwndChild ); ThreadLock(pwndChild, &tlpwndChild); if (pwndChild && FIsParentDude(pwndChild)) { /* * If this is a dialog class, then one of three things has * happened: * * o This is a static text control * o This is the background of the dialog box. * * What we do is enumerate the child windows and see if * any of them contain the current cursor point. If they do, * change our window handle and continue on. Otherwise, * return doing nothing -- we don't want context-sensitive * help for a dialog background. * * If this is a group box, then we might have clicked on a * disabled control, so we enumerate child windows to see * if we get another control. */ /* * We're enumerating a dialog's children. So, if we don't * find any matches, hwndChild will be NULL and the check * below will drop out. */ DlgEnumData.pwndDialog = pwndChild; DlgEnumData.pwndControl = NULL; DlgEnumData.ptCurHelp = msg.pt; xxxInternalEnumWindow(pwndChild, EnumPwndDlgChildProc, (LPARAM)&DlgEnumData, BWL_ENUMCHILDREN); pwndControl = DlgEnumData.pwndControl; } else { pwndControl = pwndChild; } /* * If we click on nothing, just exit. */ if (pwndControl == pwnd) { pwndControl = NULL; } /* * HACK ALERT (Visual Basic 4.0) - they have their own non-window * based controls that draw directly on the main dialog. In order * to provide help for these controls, we pass along the WM_HELP * message iff the main dialog has a context id assigned. * * If the top level window has its own context help ID, * then pass it in the context help message. */ if (!pwndControl) { if (_GetProp(pwnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), TRUE)) pwndControl = pwnd; } if (pwndControl) { PWND pwndSend; int id; TL tlpwndSend; TL tlpwndControl; ThreadLockAlways(pwndControl, &tlpwndControl); zzzSetCursor(SYSCUR(ARROW)); xxxReleaseCapture(); xxxRedrawTitle(pwnd, DC_BUTTONS); ClrWF(pwnd, WFHELPBUTTONDOWN); xxxGetMessage(&msg, NULL, 0, 0); if (FWINABLE()) { xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, INDEX_TITLEBAR_HELPBUTTON, FALSE); xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, FALSE); } /* * Determine the ID of the control * We used to always sign extend, but Win98 doesn't do that * so we only sign extend 0xffff. MCostea #218711 */ if (TestwndChild(pwndControl)) { id = PTR_TO_ID(pwndControl->spmenu); if (id == 0xffff) { id = -1; } } else { id = -1; } /* * Disabled controls and static controls won't pass this * on to their parent, so instead, we send the message to * their parent. */ if (TestWF(pwndControl, WFDISABLED)) { PWND pwndParent = _GetParent(pwndControl); if (!pwndParent) { ThreadUnlock( &tlpwndControl ); ThreadUnlock( &tlpwndChild ); return; } pwndSend = pwndParent; } else { pwndSend = pwndControl; } ThreadLockAlways(pwndSend, &tlpwndSend); xxxSendHelpMessage( pwndSend, HELPINFO_WINDOW, id, (HANDLE)HWq(pwndControl), GetContextHelpId(pwndControl)); ThreadUnlock(&tlpwndSend); ThreadUnlock(&tlpwndControl); ThreadUnlock(&tlpwndChild); return; } ThreadUnlock(&tlpwndChild); break; } else if ((msg.message == WM_RBUTTONDOWN) || (msg.message == WM_MBUTTONDOWN) || (msg.message == WM_XBUTTONDOWN)) { /* * fix bug 29852; break the loop for right and middle buttons * and pass along the messages to the control */ break; } else if (msg.message == WM_MOUSEMOVE) { if (PtInRect(&rc, msg.pt)) zzzSetCursor(SYSCUR(HELP)); else zzzSetCursor(SYSCUR(ARROW)); } else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) { xxxGetMessage( &msg, NULL, 0, 0 ); break; } xxxGetMessage(&msg, NULL, 0, 0); xxxTranslateMessage(&msg, 0); xxxDispatchMessage(&msg); } xxxReleaseCapture(); zzzSetCursor(SYSCUR(ARROW)); xxxRedrawTitle(pwnd, DC_BUTTONS); ClrWF(pwnd, WFHELPBUTTONDOWN); if (FWINABLE()) { xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, INDEX_TITLEBAR_HELPBUTTON, 0); xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0); } }
/*****************************************************************************\ * xxxGetMenuBarInfo() * * This succeeds if the menu/menu item exists. * * Parameters: * pwnd window * idObject this can be OBJID_MENU, OBJID_SYSMENU, or OBJID_CLIENT * idItem which thing do we need info on? 0..cItems. 0 indicates * the menu itself, 1 is the first item on the menu... * pmbi Pointer to a MENUBARINFO structure that gets filled in * \*****************************************************************************/ BOOL WINAPI xxxGetMenuBarInfo(PWND pwnd, long idObject, long idItem, PMENUBARINFO pmbi) { PMENU pMenu; int cBorders; PITEM pItem; PPOPUPMENU ppopup; CheckLock(pwnd); /* * Validate menubarinfo structure */ if (pmbi->cbSize != sizeof(MENUBARINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "MENUBARINFO.cbSize %d is wrong", pmbi->cbSize); return FALSE; } /* * Initialize the fields */ SetRectEmpty(&pmbi->rcBar); pmbi->hMenu = NULL; pmbi->hwndMenu = NULL; pmbi->fBarFocused = FALSE; pmbi->fFocused = FALSE; /* * Get the menu handle we will deal with. */ if (idObject == OBJID_MENU) { int cBorders; if (TestWF(pwnd, WFCHILD) || !pwnd->spmenu) return FALSE; pMenu = pwnd->spmenu; if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; /* * Menu handle */ pmbi->hMenu = PtoHq(pMenu); /* * Menu rect */ if (pMenu->cxMenu && pMenu->cyMenu) { if (!idItem) { cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER); pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER); if (TestWF(pwnd, WFCPRESENT)) { pmbi->rcBar.top += (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION)); } pmbi->rcBar.right = pmbi->rcBar.left + pMenu->cxMenu; pmbi->rcBar.bottom = pmbi->rcBar.top + pMenu->cyMenu; } else { pItem = pMenu->rgItems + idItem - 1; pmbi->rcBar.left = pwnd->rcWindow.left + pItem->xItem; pmbi->rcBar.top = pwnd->rcWindow.top + pItem->yItem; pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem; pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem; } } /* * Are we currently in app menu bar mode? */ ppopup = GetpGlobalPopupMenu(pwnd); if (ppopup && ppopup->fHasMenuBar && !ppopup->fIsSysMenu && (ppopup->spwndNotify == pwnd)) { // Yes, we are. pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem-1) { pmbi->fFocused = TRUE; UserAssert(ppopup->ppopupmenuRoot); pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup); } } } else if (idObject == OBJID_SYSMENU) { if (!TestWF(pwnd, WFSYSMENU)) return FALSE; pMenu = xxxGetSysMenu(pwnd, FALSE); if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; pmbi->hMenu = PtoHq(pMenu); /* * Menu rect */ if (_HasCaptionIcon(pwnd)) { // The menu and single item take up the same space cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER); pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER); pmbi->rcBar.right = pmbi->rcBar.left + (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CXSMSIZE) : SYSMET(CXSIZE)); pmbi->rcBar.bottom = pmbi->rcBar.top + (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMSIZE) : SYSMET(CYSIZE)); } /* * Are we currently in system menu bar mode? */ ppopup = GetpGlobalPopupMenu(pwnd); if (ppopup && ppopup->fHasMenuBar && ppopup->fIsSysMenu && (ppopup->spwndNotify == pwnd)) { // Yes, we are. pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem - 1) { pmbi->fFocused = TRUE; UserAssert(ppopup->ppopupmenuRoot); pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup); } } } else if (idObject == OBJID_CLIENT) { HMENU hMenu; hMenu = (HMENU)xxxSendMessage(pwnd, MN_GETHMENU, 0, 0); pMenu = HtoP(hMenu); if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; pmbi->hMenu = hMenu; if (!idItem) { pmbi->rcBar = pwnd->rcClient; } else { pItem = pMenu->rgItems + idItem - 1; pmbi->rcBar.left = pwnd->rcClient.left + pItem->xItem; pmbi->rcBar.top = pwnd->rcClient.top + pItem->yItem; pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem; pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem; } /* * Are we currently in popup mode with us as one of the popups * showing? */ ppopup = ((PMENUWND)pwnd)->ppopupmenu; if (ppopup && (ppopup->ppopupmenuRoot == GetpGlobalPopupMenu(pwnd))) { pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if ((UINT)idItem == ppopup->posSelectedItem + 1) { pmbi->fFocused = TRUE; pmbi->hwndMenu = HW(ppopup->spwndNextPopup); } } } else { return FALSE; } return TRUE; }
/****************************************************************************\ * * _GetTitleBarInfo() * * Gets info about a window's title bar. If the window is bogus or * doesn't have a titlebar, this will fail. * \****************************************************************************/ BOOL WINAPI xxxGetTitleBarInfo(PWND pwnd, PTITLEBARINFO ptbi) { int cxB; CheckLock(pwnd); /* * Validate titlebarinfo structure */ if (ptbi->cbSize != sizeof(TITLEBARINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "TITLEBARINFO.cbSize %d is wrong", ptbi->cbSize); return FALSE; } RtlZeroMemory(&ptbi->rgstate, sizeof(ptbi->rgstate)); ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_FOCUSABLE; if (TestWF(pwnd, WFBORDERMASK) != LOBYTE(WFCAPTION)) { // No titlebar. ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_INVISIBLE; return TRUE; } if (!TestWF(pwnd, WFMINIMIZED) && !TestWF(pwnd, WFCPRESENT)) { // Off screen (didn't fit) ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_OFFSCREEN; SetRectEmpty(&ptbi->rcTitleBar); return TRUE; } /* * Get titlebar rect */ ptbi->rcTitleBar = pwnd->rcWindow; cxB = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); InflateRect(&ptbi->rcTitleBar, -cxB * SYSMET(CXBORDER), -cxB * SYSMET(CYBORDER)); if (TestWF(pwnd, WEFTOOLWINDOW)) { ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYSMCAPTION); } else { ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYCAPTION); } /* * Don't include the system menu area! */ if (TestWF(pwnd, WFSYSMENU) && _HasCaptionIcon(pwnd)) ptbi->rcTitleBar.left += (ptbi->rcTitleBar.bottom - ptbi->rcTitleBar.top - SYSMET(CYBORDER)); /* * Close button */ if (!TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (!xxxMNCanClose(pwnd)) ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_UNAVAILABLE; if (TestWF(pwnd, WFCLOSEBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Max button */ if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (! TestWF(pwnd, WFMAXBOX)) { if (! TestWF(pwnd, WFMINBOX)) { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_UNAVAILABLE; } } if (TestWF(pwnd, WFZOOMBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Min button */ if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (! TestWF(pwnd, WFMINBOX)) { if (! TestWF(pwnd, WFMAXBOX)) { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_UNAVAILABLE; } } if (TestWF(pwnd, WFREDUCEBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Help button */ if (!TestWF(pwnd, WEFCONTEXTHELP) || TestWF(pwnd, WFMINBOX) || TestWF(pwnd, WFMAXBOX)) { ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (TestWF(pwnd, WFHELPBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_PRESSED; } // IME button BOGUS! ptbi->rgstate[INDEX_TITLEBAR_IMEBUTTON] = STATE_SYSTEM_INVISIBLE; #if 0 /* * System menu */ if (!TestWF(pwnd, WFSYSMENU) || !_HasCaptionIcon(pwnd)) ptbi->stateSysMenu |= STATE_SYSTEM_INVISIBLE; #endif return TRUE; }
void xxxCalcClientRect( PWND pwnd, LPRECT lprc, BOOL fHungRedraw) { int cxFrame, yTopOld; RECT rcTemp; PMENU pMenu; TL tlpmenu; int cBorders; BOOL fEmptyClient; CheckLock(pwnd); /* * Clear all the frame bits. NOTE: The HIBYTE of all these #defines * must stay the same for this line to work. */ ClrWF(pwnd, (WFHPRESENT | WFVPRESENT | WFCPRESENT | WFMPRESENT)); // // We need to clear the client border bits also. Otherwise, when the // window gets really small, the client border will draw over the menu // and caption. // ClrWF(pwnd, WFCEPRESENT); /* * If the window is iconic, the client area is empty. */ if (TestWF(pwnd, WFMINIMIZED)) { // SetRectEmpty(lprc); // We must make it an empty rectangle. // But, that empty rectangle should be at the top left corner of the // window rect. Else, ScreenToClient() will return bad values. lprc->right = lprc->left; lprc->bottom = lprc->top; return; } // Save rect into rcTemp for easy local calculations. CopyRect(&rcTemp, lprc); // Save the top so we'll know how tall the caption was yTopOld = rcTemp.top; // Adjustment for the caption if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) { SetWF(pwnd, WFCPRESENT); rcTemp.top += TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION); } // Subtract out window borders cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); cxFrame = cBorders * SYSMET(CXBORDER); InflateRect(&rcTemp, -cxFrame, -cBorders*SYSMET(CYBORDER)); if (!TestwndChild(pwnd) && (pMenu = pwnd->spmenu)) { SetWF(pwnd, WFMPRESENT); if (!fHungRedraw) { ThreadLockAlways(pMenu, &tlpmenu); rcTemp.top += xxxMenuBarCompute(pMenu, pwnd, rcTemp.top - yTopOld, cxFrame, rcTemp.right - rcTemp.left); ThreadUnlock(&tlpmenu); } } // // Fix for B#1425 -- Sizing window really small used to move children's // rects because the client calculations were wrong. So we make the // bottom of the client match up with the top (the bottom of the menu // bar). // fEmptyClient = FALSE; if (rcTemp.top >= rcTemp.bottom) { rcTemp.bottom = rcTemp.top; fEmptyClient = TRUE; } // // BOGUS BOGUS BOGUS // Hack for Central Point PC Tools. // Possibly for M5 only. // B#8445 // // They check for div-by-zero all over, but they jump to the wrong place // if a zero divisor is encountered, and end up faulting anyway. So this // code path was never tested basically. There's a period when starting // up where the window rect of their drives ribbon is empty. In Win3.x, // the client would be shrunk to account for the border it had, and it // would look like it wasn't empty because the width would be negative, // signed! So we version-switch this code, since other apps have // reported the non-emptiness as an annoying bug. // if (TestWF(pwnd, WFWIN40COMPAT) && (rcTemp.left >= rcTemp.right)) { rcTemp.right = rcTemp.left; fEmptyClient = TRUE; } if (fEmptyClient) goto ClientCalcEnd; // // Subtract client edge if we have space // if (TestWF(pwnd, WEFCLIENTEDGE) && (rcTemp.right - rcTemp.left >= (2 * SYSMET(CXEDGE))) && (rcTemp.bottom - rcTemp.top >= (2 * SYSMET(CYEDGE))) ) { SetWF(pwnd, WFCEPRESENT); InflateRect(&rcTemp, -SYSMET(CXEDGE), -SYSMET(CYEDGE)); } // // Subtract scrollbars // Note compatibility with 3.1: // * You don't get a horizontal scrollbar unless you have MORE // space (> ) in your client than you need for one. // * You get a vertical scrollbar if you have AT LEAST ENOUGH // space (>=) in your client for one. // if (TestWF(pwnd, WFHSCROLL) && (rcTemp.bottom - rcTemp.top > SYSMET(CYHSCROLL))) { SetWF(pwnd, WFHPRESENT); if (!fHungRedraw) rcTemp.bottom -= SYSMET(CYHSCROLL); } if (TestWF(pwnd, WFVSCROLL) && (rcTemp.right - rcTemp.left >= SYSMET(CXVSCROLL))) { SetWF(pwnd, WFVPRESENT); if (!fHungRedraw) rcTemp.right -= SYSMET(CXVSCROLL); } ClientCalcEnd: CopyRect(lprc, &rcTemp); }