Site hosted by Angelfire.com: Build your free website today!
 

Delphi Source - Limiting A Forms Size


Original Source by Fredrik Haglund - CompuServe: 100277,347.  Additional Notes from Inprise (Borland).

KEYWORDS: FORMS SIZE RESIZE DIALOGS WINDOWS WM_GETMINMAXINFO WMNCHITTEST AREA:


This is a demonstration how to limit the form size during resize and the forms position and size when it's maximized.

1. Add this line to the private section of the form declaration.

procedure WMGetMinMaxInfo( var Message :TWMGetMinMaxInfo ); message WM_GETMINMAXINFO;

2. Add this to the implementation part:

procedure TForm1.WMGetMinMaxInfo( var Message :TWMGetMinMaxInfo );
begin
  with Message.MinMaxInfo^ do
  begin
    ptMaxSize.X := 200;                {Width when maximized}
    ptMaxSize.Y := 200;                {Height when maximized}
    ptMaxPosition.X := 99;             {Left position when maximized}
    ptMaxPosition.Y := 99;             {Top position when maximized}
    ptMinTrackSize.X := 100;           {Minimum width}
    ptMinTrackSize.Y := 100;           {Minimum height}
    ptMaxTrackSize.X := 300;           {Maximum width}
    ptMaxTrackSize.Y := 300;           {Maximum height}
  end;
  Message.Result := 0;                 {Tell windows you have changed minmaxinfo}
  inherited;  
end;

NOTE! In windows 95 the screen size can change during runtime. If the Scaled property of the form is true then component size and position can change.

The WM_GETMINMAXINFO message is sent to a window whenever Windows needs the maximized position or dimensions of the window or needs the maximum or minimum tracking size of the window. The maximized size of a window is the size of the window when its borders are fully extended. The maximum tracking size of a window is the largest window size that can be achieved by using the borders to size the window. The minimum tracking size of a window is the smallest window size that can be achieved by using the borders to size the window.

Windows fills in a TMINMAXINFO data structure, specifying default values for the various positions and dimensions. The application may change these values if it processes this message. An application should return zero if it processes this message.

type
  TPoint = record
    x: Integer;
    y: Integer;
  end;
  TMinMaxInfo = record
    ptReserved: TPoint;
    ptMaxSize: TPoint;
    ptMaxPosition: TPoint;
    ptMinTrackSize: TPoint;
    ptMaxTrackSize: TPoint;
  end;
  TWMGetMinMaxInfo = record
    Msg: Cardinal;
    Unused: Integer;
    MinMaxInfo: PMinMaxInfo;
    Result: Longint;
  end;

The TWMGetMinMaxInfo type is the message record for the WM_GETMINMAXINFO message. The TMINMAXINFO structure contains information about a window's maximized size and position and its minimum and maximum tracking size.

ptReserved Reserved for internal use.

ptMaxSize Specifies the maximized width (point.x) and the maximized height (point.y) of the window.

ptMaxPosition Specifies the position of the left side of the maximized window (point.x) and the position of the top of the maximized window (point.y).

ptMinTrackSize Specifies the minimum tracking width (point.x) and the minimum tracking height (point.y) of the window.

ptMaxTrackSize Specifies the maximum tracking width (point.x) and the maximum tracking height (point.y) of the window.

The TPOINT structure defines the x- and y-coordinates of a point.


In some cases, developers would want to create a regular window (Form) in Delphi that contains some of the characteristics of a dialog box. For example, they do not want to allow their users to resize the form at runtime due to user interface design issues. Other than creating the whole form as a dialog box, there is not a property or a method to handle this in a regular window in Delphi. But due to the solid connection between Delphi and the API layer, developers can accomplish this easily. The following example demonstrates a way of handling the Windows message "WM_GetMinMaxInfo" which allows the developer to restrict the size of windows (forms) at runtime to a specific value. In this case, it will be used to disable the functionality of sizing the window (form) at runtime. Consider the following unit:

unit getminmax;

interface

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

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo);
              message WM_GETMINMAXINFO;
    procedure WMInitMenuPopup(var Msg: TWMInitMenuPopup);
              message WM_INITMENUPOPUP;
    procedure WMNCHitTest(var Msg: TWMNCHitTest);
              message WM_NCHitTest;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

 procedure TForm1.WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo);
 begin
     inherited;
     with Msg.MinMaxInfo^ do
     begin
          ptMinTrackSize.x:= form1.width;
          ptMaxTrackSize.x:= form1.width;
          ptMinTrackSize.y:= form1.height;
          ptMaxTrackSize.y:= form1.height;
     end;
 end;

 procedure TForm1.WMInitMenuPopup(var Msg: TWMInitMenuPopup);
 begin
      inherited;
      if Msg.SystemMenu then
         EnableMenuItem(Msg.MenuPopup, SC_SIZE, MF_BYCOMMAND or MF_GRAYED)
 end;

 procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
 begin
      inherited;
      with Msg do
           if Result in [HTLEFT, HTRIGHT, HTBOTTOM, HTBOTTOMRIGHT,
                     HTBOTTOMLEFT, HTTOP, HTTOPRIGHT, HTTOPLEFT] then
              Result:= HTNOWHERE
 end;
end.  { End of Unit}

A message handler for the windows message "WM_GetMinMaxInfo" in the code above was used to set the minimum and maximum TrackSize of the window to equal the width and height of the form at design time. That was actually enough to disable the resizing of the window (form), but the example went on to handle another couple of messages just to make the application look professional. The first message was the "WMInitMenuPopup" and that was to gray out the size option from the System Menu so that the application does not give the impression that this functionality is available.  The second message was the "WMNCHitTest" and that was used to disable the change of the cursor icon whenever the mouse goes over one of the borders of the window (form) for the same reason which is not to give the impression that the resizing functionality is available.