一个控件:FormSize.pas,好好看看应该能知道怎么做了。
unit FormSize;
{
************************ This component is FREE *****************************
Use this component at your own risk! Feel free to modify it (of course please
e-mail me a copy...). Good luck!
*****************************************************************************
Unit :FormSizer.Pas - Delphi VCL component
Date :16/08/1996
Creator :Madaffari Giuseppe - SoftPlus (giumad@antares.it)
Version :1.00
This unit is designed to extend forms functionality. Based on original idea of Michael
Novak (mjn@ksu.ksu.edu) and developed for the Delphi-Talk mailing list subscribers.
Hope you find it useful. Any comment and suggestion please forward to:
Giuseppe Madaffari - giumad@antares.it
How to use TFormSizer component:
This component work to give you additional control over TForm behaviour. Dropping
this non-visual control on a form, you will be able to set a lot of extra informations for the
internal window management. The new available properties are:
MinTrackHeight : the minimum height a window can be resized to;
MinTrackWidth : the minimum width a window can be resized to;
MaxTrackHeight : the maximum height a window can be resized to;
MaxTrackWidth : the minimum width a window can be resized to;
MaximizedHeight : the height of the maximized window;
MaximizedWidth : the height of the maximized window;
MaximizedTop : the x-coordinate of the top left corner of a maximized window;
MaximizedLeft : the y-coordinate of the top left corner of a maximized window;
UseDesignTimeDef : the control'properties will be set to the design time's value;
Events : indicate what events must be hooked;
The only available event is OnTracking which is called wenever Window need to retrieve
the tracking information for a window (message WM_GETMINMAXINFO). You could use
this event to dynamically change the values setted at design time.
N.B.: in order to enable the component, you must insert a call to the method Activate
in the OnCreate handler of the form. Setting any of the above properties to the value of 0,
means that Window will use the default values for the specific window class.
}
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics, Controls, Forms, Dialogs,stdctrls;
type
TCoordinate=(ctNone, ctEquals, ctGreater, ctLess);
TNotifyOnTracking = procedure(Sender: TObject; Var Info: TMINMAXINFO) of object;
TFormSizer = class(TComponent)
private
FMinTrackHeight : integer;
FMinTrackWidth : integer;
FMaxTrackHeight : integer;
FMaxTrackWidth : integer;
FMaximizedHeight : integer;
FMaximizedTop : integer;
FMaximizedWidth : integer;
FEnabled : Boolean;
FOnTracking : TNotifyOnTracking;
FMaximizedLeft : integer;
FUseDesignTimeDef : Boolean;
FTop : integer;
FLeft : integer;
FCoordType : TCoordinate;
Procedure SetEnabled(Value:Boolean);
Procedure SetUseDesignTimeDef(Value:Boolean);
Procedure SetTop(Value:Integer);
Procedure SetLeft(Value:Integer);
Procedure SetCoordType(Value:TCoordinate);
protected
FOldWndProc
ointer;
FExtWndProc:TFarProc;
Procedure ExtWndProc(Var Msg:TMessage);
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
Procedure Activate;
published
Property MinTrackHeight : integer read FMinTrackHeight write FMinTrackHeight default 0;
Property MinTrackWidth : integer read FMinTrackWidth write FMinTrackWidth default 0;
Property MaxTrackHeight : integer read FMaxTrackHeight write FMaxTrackHeight default 0;
Property MaxTrackWidth : integer read FMaxTrackWidth write FMaxTrackWidth default 0;
Property MaximizedHeight : integer read FMaximizedHeight write FMaximizedHeight default 0;
Property MaximizedTop : integer read FMaximizedTop write FMaximizedTop default 0;
Property MaximizedWidth : integer read FMaximizedWidth write FMaximizedWidth default 0;
Property Enabled : Boolean read FEnabled write SetEnabled default False;
Property OnTracking : TNotifyOnTracking read FOnTracking write FOnTracking ;
Property MaximizedLeft : integer read FMaximizedLeft write FMaximizedLeft default 0;
Property UseDesignTimeDef : Boolean read FUseDesignTimeDef write SetUseDesignTimeDef default False;
Property Top : integer read FTop write SetTop default 0;
Property Left : integer read FLeft write SetLeft default 0;
Property CoordType : TCoordinate read FCoordType write SetCoordType default ctNone;
Property Name;
Property Tag;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples',[TFormSizer]);
end;
Procedure TFormSizer.SetEnabled(Value:Boolean);
begin
if (Owner is TForm) then begin
if not FEnabled and Value then
FOldWndProc:=Pointer(SetWindowLong((Owner as TForm).Handle, GWL_WNDPROC, LongInt(FExtWndProc)))
else if FEnabled and not Value then
SetWindowLong((Owner as TForm).Handle, GWL_WNDPROC, LongInt(FOldWndProc));
FEnabled:=Value;
with (Owner as TForm) do
MoveWindow(Handle, Left, Top, Width, Height, True);
SetCoordType(FCoordType);
end
else
MessageDlg('TFormSizer error.'#13'Component''s owner must be a form.', mtWarning, [mbOk], 0);
end;
Procedure TFormSizer.SetUseDesignTimeDef(Value:Boolean);
begin
if (Owner is TForm) then begin
if Value then with Owner as TForm do begin
FMinTrackHeight := Height;
FMinTrackWidth := Width;
FMaxTrackHeight := Height;
FMaxTrackWidth := Width;
FMaximizedHeight := Height;
FMaximizedTop := Top;
FMaximizedWidth := Width;
FMaximizedLeft := Left;
FTop := Top;
FLeft := Left;
end
else begin
FMinTrackHeight := 0;
FMinTrackWidth := 0;
FMaxTrackHeight := 0;
FMaxTrackWidth := 0;
FMaximizedHeight := 0;
FMaximizedTop := 0;
FMaximizedWidth := 0;
FMaximizedLeft := 0;
FTop := 0;
FLeft := 0;
end;
FUseDesignTimeDef := Value;
end
else
MessageDlg('TFormSizer error.'#13'Component''s owner must be a form.', mtWarning, [mbOk], 0);
end;
Procedure TFormSizer.SetTop(Value:Integer);
begin
FTop:=Value;
SetCoordType(FCoordType);
end;
Procedure TFormSizer.SetLeft(Value:Integer);
begin
FLeft:=Value;
SetCoordType(FCoordType);
end;
Procedure TFormSizer.SetCoordType(Value:TCoordinate);
begin
FCoordType:=Value;
if not FEnabled then Exit;
if (Owner is TForm) then
with (Owner as TForm) do
case FCoordType of
ctEquals:begin
if Left〈〉FLeft then Left:=FLeft;
if Top〈〉FTop then Top:=FTop;
end;
ctGreater:begin
if Left<FLeft then Left:=FLeft;
if Top<FTop then Top:=FTop;
end;
ctLess:begin
if Left>FLeft then Left:=FLeft;
if Top>FTop then Top:=FTop;
end;
end;
end;
constructor TFormSizer.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FMinTrackHeight := 0;
FMinTrackWidth := 0;
FMaxTrackHeight := 0;
FMaxTrackWidth := 0;
FMaximizedHeight := 0;
FMaximizedTop := 0;
FMaximizedWidth := 0;
FEnabled := False;
FMaximizedLeft := 0;
FUseDesignTimeDef := False;
FTop := 0;
FLeft := 0;
FCoordType := ctNone;
FExtWndProc := MakeObjectInstance(ExtWndProc);
end;
destructor TFormSizer.Destroy;
begin
if FEnabled and (Owner is TForm) then
SetWindowLong((Owner as TForm).Handle, GWL_WNDPROC, LongInt(FOldWndProc));
FreeObjectInstance(FExtWndProc);
inherited Destroy;
end;
Procedure TFormSizer.Activate;
begin
SetEnabled(True);
end;
Procedure TFormSizer.ExtWndProc(Var Msg:TMessage);
var Info:TMINMAXINFO;
begin
with Msg do begin
if Msg=WM_GETMINMAXINFO then begin
Info:=PMINMAXINFO(lParam)^;
if FMinTrackHeight>0 then
Info.ptMinTrackSize.Y := FMinTrackHeight;;
if FMinTrackWidth>0 then
Info.ptMinTrackSize.X := FMinTrackWidth;
if FMaxTrackWidth>0 then
Info.ptMaxTrackSize.X := FMaxTrackWidth;
if FMaxTrackHeight>0 then
Info.ptMaxTrackSize.Y := FMaxTrackHeight;
if FMaximizedHeight>0 then
Info.ptMaxSize.Y := FMaximizedHeight;
if FMaximizedWidth>0 then
Info.ptMaxSize.X := FMaximizedWidth;;
if FMaximizedLeft>0 then
Info.ptMaxPosition.X := FMaximizedLeft;
if FMaximizedTop>0 then
Info.ptMaxPosition.Y :=FMaximizedTop;
if (Assigned(FOnTracking)) and not (csDesigning in ComponentState) then
FOnTracking(Self, Info);
PMINMAXINFO(lParam)^:=Info;
end;
if (Msg=WM_MOVE) then
SetCoordType(FCoordType);
Result:=CallWindowProc(FOldWndProc, (Owner as TForm).Handle, Msg, wParam, lParam);
if (Msg=WM_NCHITTEST) and
(FCoordType=ctEquals) and
(Result=HTCAPTION) then
Result:=HTCLIENT;
end;
end;
end.