You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.6 KiB
198 lines
6.6 KiB
/****************************** 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);
|
|
}
|