With these few lines of code you can easily setup a user-interface where users can move and resize controls at run-time. The trick behind it is two lines that should be put in the OnMouseDown-handler for the controls which are to be affected:
ReleaseCapture;
(Sender as TWinControl).Perform(WM_SYSCOMMAND, CODE, 0);
CODE is the value that sets the action to be performed, (read more about it in Win-API Help).
The demo below consists of a form with a GroupBox and a Button. These are the target-controls. There are also four buttons with these options to choose from:
Move Controls
Resize Controls
Control Mode - Sets the controls in normal action.
Save - Lets you save the controls top-, left-, height- and width- values to an Inifile. The values are restored at next Form-creation.
// Resize and move controls at run-time demonstration.
// Save / restore changes.
//
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, IniFiles;
type
TForm1 = class(TForm)
Button1: TButton;
GroupBox1: TGroupBox;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
procedure ChangePosition(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ChangeSize(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// Useable codes:
// SC_MOVE-8 Resize
// SC_MOVE+2 Position
// SC_MAXIMIZE
// SC_RESTORE
procedure TForm1.ChangeSize(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
(Sender as TWinControl).Perform(WM_SYSCOMMAND, SC_MOVE -8, 0);
end;
procedure TForm1.ChangePosition(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
(Sender as TWinControl).Perform(WM_SYSCOMMAND, SC_MOVE + 2, 0);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Button1.OnMouseDown:= ChangeSize;
GroupBox1.OnMouseDown:= ChangeSize;
Button1.Caption:= 'Resize me';
GroupBox1.Caption:= 'Resize me';
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Button1.OnMouseDown:= nil;
GroupBox1.OnMouseDown:= nil;
Button1.Caption:= 'Normal';
GroupBox1.Caption:= 'Normal';
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Button1.OnMouseDown:= ChangePosition;
GroupBox1.OnMouseDown:= ChangePosition;
Button1.Caption:= 'Move me';
GroupBox1.Caption:= 'Move me';
end;
// Restore control-values from inifile
procedure TForm1.FormCreate(Sender: TObject);
var IniFile: TIniFile;
n: integer;
begin
IniFile:= TIniFile.Create('ctrls.ini');
for n:=0 to ControlCount - 1 do
begin
Controls[n].Top:= IniFile.ReadInteger(Controls[n].Name, 'Top', Controls[n].Top);
Controls[n].Left:= IniFile.ReadInteger(Controls[n].Name, 'Left', Controls[n].Left);
Controls[n].Height:= IniFile.ReadInteger(Controls[n].Name, 'Height', Controls[n].Height);
Controls[n].Width:= IniFile.ReadInteger(Controls[n].Name, 'Width', Controls[n].Width);
end;
IniFile.Free;
Button1.Caption:= 'Normal';
GroupBox1.Caption:= 'Normal';
end;
// Save control-values to inifile
procedure TForm1.Button5Click(Sender: TObject);
var IniFile: TIniFile;
n: integer;
begin
IniFile:= TIniFile.Create('ctrls.ini');
for n:=0 to ControlCount - 1 do
begin
IniFile.WriteInteger(Controls[n].Name, 'Top', Controls[n].Top);
IniFile.WriteInteger(Controls[n].Name, 'Left', Controls[n].Left);
IniFile.WriteInteger(Controls[n].Name, 'Height', Controls[n].Height);
IniFile.WriteInteger(Controls[n].Name, 'Width', Controls[n].Width);
end;
IniFile.Free;
end;
end.