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
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...
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.
"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--}
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