Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

339 lines
11 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
resize.c
Abstract:
This file implements window resizing.
Author:
Therese Stowell (thereses) 6-Oct-1991
Revision History:
Notes:
--*/
#include "precomp.h"
#pragma hdrstop
extern SHORT VerticalScrollSize;
extern SHORT HorizontalScrollSize;
extern SHORT VerticalClientToWindow;
extern SHORT HorizontalClientToWindow;
//#define THERESES_DEBUG 1
VOID
CalculateNewSize(
IN PBOOLEAN MaximizedX,
IN PBOOLEAN MaximizedY,
IN OUT PSHORT DeltaX,
IN OUT PSHORT DeltaY,
IN SHORT WindowSizeX,
IN SHORT WindowSizeY,
IN COORD ScreenBufferSize,
IN COORD FontSize
);
VOID
ProcessResizeWindow(
IN PSCREEN_INFORMATION ScreenInfo,
IN PCONSOLE_INFORMATION Console,
IN LPWINDOWPOS WindowPos
)
{
SHORT DeltaX,DeltaY;
SHORT PixelDeltaX,PixelDeltaY;
DWORD Flags=0;
COORD FontSize;
#ifdef THERESES_DEBUG
DbgPrint("WM_WINDOWPOSCHANGING message ");
DbgPrint(" WindowSize is %d %d\n",CONSOLE_WINDOW_SIZE_X(ScreenInfo),CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
DbgPrint(" WindowRect is %d %d %d %d\n",Console->WindowRect.left,
Console->WindowRect.top,
Console->WindowRect.right,
Console->WindowRect.bottom);
DbgPrint(" window pos is %d %d %d %d\n",WindowPos->x,
WindowPos->y,
WindowPos->cx,
WindowPos->cy);
#endif
//
// If the window is not being resized, don't do anything
//
if (WindowPos->flags & SWP_NOSIZE) {
return;
}
if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
FontSize = ScreenInfo->BufferInfo.TextInfo.FontSize;
} else {
FontSize.X = 1;
FontSize.Y = 1;
}
//
// If the frame changed, update the system metrics
//
if (WindowPos->flags & SWP_FRAMECHANGED) {
InitializeSystemMetrics();
if (Console->VerticalClientToWindow != VerticalClientToWindow ||
Console->HorizontalClientToWindow != HorizontalClientToWindow) {
Console->VerticalClientToWindow = VerticalClientToWindow;
Console->HorizontalClientToWindow = HorizontalClientToWindow;
Console->WindowRect.left = WindowPos->x;
Console->WindowRect.top = WindowPos->y;
Console->WindowRect.right = WindowPos->x + WindowPos->cx;
Console->WindowRect.bottom = WindowPos->y + WindowPos->cy;
ScreenInfo->MaxWindow.X = ScreenInfo->MaximumWindowSize.X*FontSize.X + VerticalClientToWindow;
ScreenInfo->MaxWindow.Y = ScreenInfo->MaximumWindowSize.Y*FontSize.Y + HorizontalClientToWindow;
return;
}
}
PixelDeltaX = (SHORT)(WindowPos->cx - (Console->WindowRect.right - Console->WindowRect.left));
PixelDeltaY = (SHORT)(WindowPos->cy - (Console->WindowRect.bottom - Console->WindowRect.top));
if (WindowPos->cx >= (ScreenInfo->ScreenBufferSize.X * FontSize.X + VerticalClientToWindow) &&
WindowPos->cy >= (ScreenInfo->ScreenBufferSize.Y * FontSize.Y + HorizontalClientToWindow)) {
//
// handle maximized case
//
ScreenInfo->WindowMaximizedX = TRUE;
ScreenInfo->WindowMaximizedY = TRUE;
DeltaX = (SHORT)(ScreenInfo->ScreenBufferSize.X - CONSOLE_WINDOW_SIZE_X(ScreenInfo));
DeltaY = (SHORT)(ScreenInfo->ScreenBufferSize.Y - CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
} else {
DeltaX = PixelDeltaX / FontSize.X;
DeltaY = PixelDeltaY / FontSize.Y;
//
// the only time we will get a WM_WINDOWPOSCHANGING message to grow the
// window larger than the maximum window size is when another app calls
// SetWindowPos for our window. the program manager does that when
// the user requests Tiling.
//
CalculateNewSize(&ScreenInfo->WindowMaximizedX,
&ScreenInfo->WindowMaximizedY,
&DeltaX,
&DeltaY,
(SHORT)(CONSOLE_WINDOW_SIZE_X(ScreenInfo)),
(SHORT)(CONSOLE_WINDOW_SIZE_Y(ScreenInfo)),
ScreenInfo->ScreenBufferSize,
FontSize
);
#ifdef THERESES_DEBUG
DbgPrint("Delta X Y is now %d %d\n",DeltaX,DeltaY);
DbgPrint("Maximized X Y is now %d %d\n",ScreenInfo->WindowMaximizedX,ScreenInfo->WindowMaximizedY);
#endif
}
//
// don't move window when resizing less than a column or row.
//
if (!DeltaX && !DeltaY && (PixelDeltaX || PixelDeltaY)) {
COORD OriginDifference;
//
// handle tiling case. tiling can move the window without resizing, but using
// a size message. we detect this by checking for the window origin changed by
// more than one character.
//
OriginDifference.X = (SHORT)(WindowPos->x - Console->WindowRect.left);
OriginDifference.Y = (SHORT)(WindowPos->y - Console->WindowRect.top);
if (OriginDifference.X < FontSize.X && OriginDifference.X > -FontSize.X &&
OriginDifference.Y < FontSize.Y && OriginDifference.Y > -FontSize.Y) {
WindowPos->x = Console->WindowRect.left;
WindowPos->y = Console->WindowRect.top;
WindowPos->cx = Console->WindowRect.right - Console->WindowRect.left;
WindowPos->cy = Console->WindowRect.bottom - Console->WindowRect.top;
return;
}
}
Flags |= RESIZE_SCROLL_BARS;
WindowPos->cx = (DeltaX + CONSOLE_WINDOW_SIZE_X(ScreenInfo)) * FontSize.X + (!ScreenInfo->WindowMaximizedY * VerticalScrollSize) + VerticalClientToWindow;
//
// handle the case where the window is resized to the height of the
// title bar.
//
if ((DeltaY + CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) <= 0) {
DeltaY = (SHORT)(-CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
WindowPos->cy = HorizontalClientToWindow;
} else {
WindowPos->cy = (DeltaY + CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) * FontSize.Y + (!ScreenInfo->WindowMaximizedX * HorizontalScrollSize) + HorizontalClientToWindow;
}
//
// reflect the new window size in the
// console window structure
//
{
SHORT ScrollRange,ScrollPos;
//
// PercentFromTop = ScrollPos / ScrollRange;
// PercentFromBottom = (ScrollRange - ScrollPos) / ScrollRange;
//
// if drag top border up
// Window.Top -= NumLines * PercentFromBottom;
// Window.Bottom += NumLines - (NumLines * PercentFromBottom);
//
// if drag top border down
// Window.Top += NumLines * PercentFromBottom;
// Window.Bottom -= NumLines - (NumLines * PercentFromBottom);
//
// if drag bottom border up
// Window.Top -= NumLines * PercentFromTop;
// Window.Bottom += NumLines - (NumLines * PercentFromTop);
//
// if drag bottom border down
// Window.Top += NumLines * PercentFromTop;
// Window.Bottom -= NumLines - (NumLines * PercentFromTop);
//
ScrollRange = (SHORT)(ScreenInfo->ScreenBufferSize.X - CONSOLE_WINDOW_SIZE_X(ScreenInfo));
ScrollPos = ScreenInfo->Window.Left;
if (WindowPos->x != Console->WindowRect.left) {
SHORT NumLinesFromRight;
if (ScrollRange) {
NumLinesFromRight = DeltaX * (ScrollRange - ScrollPos) / ScrollRange;
} else {
NumLinesFromRight = DeltaX; // have scroll pos at left edge
}
ScreenInfo->Window.Left -= DeltaX - NumLinesFromRight;
ScreenInfo->Window.Right += NumLinesFromRight;
} else {
SHORT NumLinesFromLeft;
if (ScrollRange) {
NumLinesFromLeft = DeltaX * ScrollPos / ScrollRange;
} else {
NumLinesFromLeft = 0; // have scroll pos at left edge
}
ScreenInfo->Window.Left -= NumLinesFromLeft;
ScreenInfo->Window.Right += DeltaX - NumLinesFromLeft;
}
ScrollRange = (SHORT)(ScreenInfo->ScreenBufferSize.Y - CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
ScrollPos = ScreenInfo->Window.Top;
if (WindowPos->y != Console->WindowRect.top) {
SHORT NumLinesFromBottom;
if (ScrollRange) {
NumLinesFromBottom = DeltaY * (ScrollRange - ScrollPos) / ScrollRange;
} else {
NumLinesFromBottom = DeltaY; // have scroll pos at top edge
}
ScreenInfo->Window.Top -= DeltaY - NumLinesFromBottom;
ScreenInfo->Window.Bottom += NumLinesFromBottom;
} else {
SHORT NumLinesFromTop;
if (ScrollRange) {
NumLinesFromTop = DeltaY * ScrollPos / ScrollRange;
} else {
NumLinesFromTop = 0; // have scroll pos at top edge
}
ScreenInfo->Window.Top -= NumLinesFromTop;
ScreenInfo->Window.Bottom += DeltaY - NumLinesFromTop;
}
}
if (ScreenInfo->WindowMaximizedX)
ASSERT (CONSOLE_WINDOW_SIZE_X(ScreenInfo) == ScreenInfo->ScreenBufferSize.X);
if (ScreenInfo->WindowMaximizedY)
ASSERT (CONSOLE_WINDOW_SIZE_Y(ScreenInfo) == ScreenInfo->ScreenBufferSize.Y);
#ifdef THERESES_DEBUG
DbgPrint(" WindowSize is now %d %d\n",CONSOLE_WINDOW_SIZE_X(ScreenInfo),CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
DbgPrint(" window pos is now %d %d %d %d\n",WindowPos->x,
WindowPos->y,
WindowPos->cx,
WindowPos->cy);
#endif
Console->ResizeFlags = Flags | (Console->ResizeFlags & SCREEN_BUFFER_CHANGE);
}
VOID
CalculateNewSize(
IN PBOOLEAN MaximizedX,
IN PBOOLEAN MaximizedY,
IN OUT PSHORT DeltaX,
IN OUT PSHORT DeltaY,
IN SHORT WindowSizeX,
IN SHORT WindowSizeY,
IN COORD ScreenBufferSize,
IN COORD FontSize
)
{
SHORT MaxDeltaX = ScreenBufferSize.X - WindowSizeX;
SHORT MaxDeltaY = ScreenBufferSize.Y - WindowSizeY;
while (TRUE) {
/*
* Do we need to remove a horizontal scroll bar?
*/
if (!*MaximizedX && *DeltaX >= MaxDeltaX) {
*MaximizedX = TRUE;
*DeltaY += VerticalScrollSize / FontSize.Y;
}
/*
* Do we need to remove a vertical scroll bar?
*/
else if (!*MaximizedY && *DeltaY >= MaxDeltaY) {
*MaximizedY = TRUE;
*DeltaX += HorizontalScrollSize / FontSize.X;
}
/*
* Do we need to add a horizontal scroll bar?
*/
else if (*MaximizedX && *DeltaX < MaxDeltaX) {
*MaximizedX = FALSE;
*DeltaY -= (VerticalScrollSize+FontSize.Y-1) / FontSize.Y;
}
/*
* Do we need to add a vertical scroll bar?
*/
else if (*MaximizedY && *DeltaY < MaxDeltaY) {
*MaximizedY = FALSE;
*DeltaX -= (HorizontalScrollSize+FontSize.X-1) / FontSize.X;
}
/*
* Everything is done, so get out.
*/
else {
if (*DeltaX > MaxDeltaX)
*DeltaX = MaxDeltaX;
if (*DeltaY > MaxDeltaY)
*DeltaY = MaxDeltaY;
return;
}
}
}