|
|
/****************************** Module Header ******************************\
* Module Name: calcclrc.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * History: * 10-22-90 MikeHar Ported functions from Win 3.0 sources. * 01-Feb-1991 mikeke Added Revalidation code \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* xxxCalcClientRect * * 10-22-90 MikeHar Ported function from Win 3.0 sources. \***************************************************************************/ VOID xxxCalcClientRect( PWND pwnd, LPRECT lprc, BOOL fHungRedraw) { int cxFrame, yTopOld, cBorders; RECT rcTemp; PMENU pMenu; TL tlpMenu; BOOL fEmptyClient; BYTE bFramePresent;
CheckLock(pwnd); UserAssert(IsWinEventNotifyDeferredOK());
bFramePresent = TestWF(pwnd, WFFRAMEPRESENTMASK);
/*
* Clear all the frame bits. NOTE: The HIBYTE of all these #defines * must stay the same for this line to work. */ ClrWF(pwnd, WFFRAMEPRESENTMASK);
//
// 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; goto CalcClientDone; }
// 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 += GetCaptionHeight(pwnd); }
// Subtract out window borders
cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); cxFrame = cBorders * SYSMETFROMPROCESS(CXBORDER); InflateRect(&rcTemp, -cxFrame, -cBorders * SYSMETFROMPROCESS(CYBORDER));
if (!TestwndChild(pwnd) && (pMenu = pwnd->spmenu)) { SetWF(pwnd, WFMPRESENT); if (!fHungRedraw) { ThreadLockMenuAlwaysNoModify(pMenu, &tlpMenu); rcTemp.top += xxxMenuBarCompute(pMenu, pwnd, rcTemp.top - yTopOld, cxFrame, rcTemp.right - rcTemp.left); ThreadUnlockMenuNoModify(&tlpMenu); } }
/*
* We should have cleared WFMPRESENT in the else case here. Win9x doesn't do * it either. Any code checking this flag will do the wrong thing... * It seems that it's pretty unsual for apps to remove the menu.... * No code checking this flag can assume that pwnd->spmenu is not NULL -- we * would need to clear it way earlier (at unlock time) for such assumption to hold true. */
//
// 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 * SYSMETFROMPROCESS(CXEDGE))) && (rcTemp.bottom - rcTemp.top >= (2 * SYSMETFROMPROCESS(CYEDGE))) ) { SetWF(pwnd, WFCEPRESENT); InflateRect(&rcTemp, -SYSMETFROMPROCESS(CXEDGE), -SYSMETFROMPROCESS(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 > SYSMETFROMPROCESS(CYHSCROLL))) { SetWF(pwnd, WFHPRESENT); if (!fHungRedraw) { rcTemp.bottom -= SYSMETFROMPROCESS(CYHSCROLL); } }
if (TestWF(pwnd, WFVSCROLL) && (rcTemp.right - rcTemp.left >= SYSMETFROMPROCESS(CXVSCROLL))) { SetWF(pwnd, WFVPRESENT); if (!fHungRedraw) { if ((!!TestWF(pwnd, WEFLEFTSCROLL)) ^ (!!TestWF(pwnd, WEFLAYOUTRTL))) { rcTemp.left += SYSMETFROMPROCESS(CXVSCROLL); } else { rcTemp.right -= SYSMETFROMPROCESS(CXVSCROLL); } } }
ClientCalcEnd:
CopyRect(lprc, &rcTemp);
CalcClientDone: if (bFramePresent != TestWF(pwnd, WFFRAMEPRESENTMASK)) { xxxWindowEvent(EVENT_OBJECT_REORDER, pwnd, OBJID_WINDOW, 0, WEF_USEPWNDTHREAD); } }
/***************************************************************************\
* UpdateClientRect() * * Make sure the client rect reflects the window styles correctly. * * 10-22-90 MikeHar Ported function from Win 3.0 sources. \***************************************************************************/ VOID xxxUpdateClientRect( PWND pwnd) { RECT rc;
CopyRect(&rc, &pwnd->rcWindow); xxxCalcClientRect(pwnd, &rc, FALSE); CopyRect(&pwnd->rcClient, &rc); }
|