Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Resizing of a form with size constraints

1,144 views
Skip to first unread message

Dmitri Papichev

unread,
Apr 19, 2001, 9:12:58 AM4/19/01
to
Hello,

As soon as form's Constraints.MinHeight and/or MinWidth properties are set
to non-zero values, the Delphi form doesn't allow to resize itself below
these values, and that's what it is all about. But the behaviour here is
somewhat different from what we can expect.

If we start to resize a form with a mouse and the resizing frame reaches
minimum values, it doesn't stop at that point but continues to follow a
mouse. When we finish resizing, the frame bounces back to minimum allowed
width/height. The different behaviour can be found in, say, Microsoft
applications (e.g MS Paint), where the resizing frame stops at the point
where minimum size is reached. The diference would be not too significant if
the way resizing is done in Delphi apps had not one unpleasant effect.
If you start resizing a Delphi constrained form dragging the top or left
border and go below minimum allowed size, the resizing frame doesn't bounce
back. Instead, the form left an top corners follow resizing frame's left and
top first, and then width and/or height is being adjusted - so the form
moves, which we didn't want it to do.

The question is: what is the best way to implement "Microsoft style" of
resizing - with resizing frame which stops when the minimum size is reached?

Thanks in advance,
Dmitri Papichev

Andreas Hammar

unread,
Apr 19, 2001, 11:33:02 AM4/19/01
to

Handle the WM_GETMINMAXINFO message.
Example code:

//----------------------START CODE ------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
private
procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message
WM_GETMINMAXINFO;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
begin
Message.MinMaxInfo.ptMinTrackSize := Point(400,300);
end;

end.

// -------------------------END CODE -------------------

This should do the job!


Andreas Hammar <andreas...@c2i.net>
---------------------------------------
A computer does what you told it to do,
not necessarily what you expected...

Peter Below (TeamB)

unread,
Apr 19, 2001, 3:21:55 PM4/19/01
to
In article <3adee481$1_1@dnews>, Dmitri Papichev wrote:
> The question is: what is the best way to implement "Microsoft style" of
> resizing - with resizing frame which stops when the minimum size is reached?

Handle the WM_SIZING Message.


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Dmitri Papichev

unread,
Apr 20, 2001, 11:02:56 AM4/20/01
to
Hello,

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote in message
news:VA.00006e1...@antispam.compuserve.com...


> In article <3adee481$1_1@dnews>, Dmitri Papichev wrote:
> > The question is: what is the best way to implement "Microsoft style" of
> > resizing - with resizing frame which stops when the minimum size is
reached?
>
> Handle the WM_SIZING Message.

Thanks a lot, Peter. WM_SIZING was the single word I had somehow missed.
All works fine now (see below my implementation of the corrected behaviour
of a form with size constraints).

Best regards,
Dmitri Papichev


[...]
procedure WMSizing (var AMessage: TMessage); message WM_SIZING;
[...]
{---------------------------------------------------------------------------
---}
procedure TDPForm.WMSizing (var AMessage: TMessage);
var
ARect: TRect;
begin
ARect := PRect (AMessage.LParam)^;

try
with Constraints do begin
if ((MinWidth > 0) AND (ARect.Right < ARect.Left + MinWidth)) then
begin
case AMessage.WParam of
WMSZ_LEFT, WMSZ_TOPLEFT, WMSZ_BOTTOMLEFT:
begin
ARect.Left := ARect.Right - MinWidth;
end;
WMSZ_RIGHT, WMSZ_TOPRIGHT, WMSZ_BOTTOMRIGHT:
begin
ARect.Right := ARect.Left + MinWidth;
end;
end; {case}
end; {if}

if ((MinHeight > 0) AND (ARect.Bottom < ARect.Top + MinHeight))
then begin
case AMessage.WParam of
WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT:
begin
ARect.Top := ARect.Bottom - MinHeight;
end;
WMSZ_BOTTOM, WMSZ_BOTTOMLEFT, WMSZ_BOTTOMRIGHT:
begin
ARect.Bottom := ARect.Top + MinHeight;
end;
end; {case}
end; {if}

if ((MaxWidth > 0) AND (ARect.Right > ARect.Left + MaxWidth)) then
begin
case AMessage.WParam of
WMSZ_LEFT, WMSZ_TOPLEFT, WMSZ_BOTTOMLEFT:
begin
ARect.Left := ARect.Right - MaxWidth;
end;
WMSZ_RIGHT, WMSZ_TOPRIGHT, WMSZ_BOTTOMRIGHT:
begin
ARect.Right := ARect.Left + MaxWidth;
end;
end; {case}
end; {if}

if ((MaxHeight > 0) AND (ARect.Bottom > ARect.Top + MaxHeight))
then begin
case AMessage.WParam of
WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT:
begin
ARect.Top := ARect.Bottom - MaxHeight;
end;
WMSZ_BOTTOM, WMSZ_BOTTOMLEFT, WMSZ_BOTTOMRIGHT:
begin
ARect.Bottom := ARect.Top + MaxHeight;
end;
end; {case}
end; {if}
end; {with}
finally
PRect(AMessage.LParam)^ := ARect;
end; {if}
end; {--TDPForm.WMSizing--}

Joris Van Damme

unread,
Apr 20, 2001, 2:36:32 PM4/20/01
to
"Peter Below (TeamB)" wrote:
> Handle the WM_SIZING Message.

Peter,

I thought WM_GETMINMAXINFO was the thing. But if you say WM_SIZING is,
than I guess I was wrong. Or does the default handler of WM_SIZING in
turn use WM_GETMINMAXINFO or something?

Joris

Peter Below (TeamB)

unread,
Apr 21, 2001, 8:42:09 AM4/21/01
to
In article <3AE081B0...@planetinternet.be>, Joris Van Damme wrote:
> I thought WM_GETMINMAXINFO was the thing. But if you say WM_SIZING is,
> than I guess I was wrong. Or does the default handler of WM_SIZING in
> turn use WM_GETMINMAXINFO or something?
>
The messages serve different purposes. If you grab a window by the
border with the mouse and drag it a WM_SIZING Message is send to the
window for each movement of the mouse. This is independ of the "drag
full window" flag, so even works if only a sizing frame is dragged. The
WM_GETMINMAXINFO message is only send on each mouse move if "drag full
window" is true, otherwise it will be send only once when the drag
finishes. And that is of course a bit late to restrict the size of the
drag frame, even though it does effect the resulting size of the window.
0 new messages