SRL Archive - Outdated Tutorials

Making Nesting Forms


A G E N T

2007-06-26 23:26:24

Hi everyone, now that I'm back onto SRL-forums, I decided to impart some of my (limited) knowledge to you. :) This tutorial will cover how to make a form that can have a button that opens up a Settings menu, PlayerForm, etc. This tutorial assumes that you have basic knowledge of forms. Let us commence!

First, you must set up a "base" form. This should have a title, start button, and room for two+ other buttons, along with whatever else you want to have.

I made a basic form for the purposes of this tutorial, with a title, settings button, and start button. The script will refer to the form as frmDesign (the default)Here is what your code should look like:

program New;
var
frmDesign : TForm;
Label1 : TLabel;
Button1 : TButton;
Button2 : TButton;

procedure InitForm;
begin;
frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 696;
frmDesign.Height := 480;
frmDesign.Caption := 'frmDesign';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := True;
frmDesign.PixelsPerInch := 96;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 222;
Label1.Top := 22;
Label1.Width := 255;
Label1.Height := 48;
Label1.Caption := 'This Is A Form';
Label1.Font.Color := clWindowText;
Label1.Font.Height := -40;
Label1.Font.Name := 'MS Sans Serif';
Label1.Font.Style := [];
Label1.ParentFont := False;
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 287;
Button1.Top := 358;
Button1.Width := 91;
Button1.Height := 50;
Button1.Caption := 'Start The Script';
Button1.TabOrder := 8;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 45;
Button2.Top := 189;
Button2.Width := 75;
Button2.Height := 31;
Button2.Caption := 'Settings';
Button2.TabOrder := 9;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.

At this point, you will have to design your second form, for example, a settings form. For clarity's sake I will just make a blank form, with a save button.

Obviously you will want to put options on it for your script. There are good tutorials out there that can teach you how to make good forms. Make and save your form, load it, and paste in the variables, changing the name, frmDesign, to Settings. Make sure you change EVERY time frmDesign occurs in the new form and new variables to Settings.

Add Settings and Button3 to the variables, then make a new procedure called InitForm2 and proceed as you did with InitForm. Make sure to change frmDesign to Settings, and create more of the stock procedures: SafeInitForm2, ShowFormModal2, SafeShowFormModal2.

program New;
var
frmDesign : TForm;
Settings : TForm;
Label1 : TLabel;
Label2 : TLabel;
Button1 : TButton;
Button2 : TButton;
Button3 : TButton;

procedure InitForm;
begin;
frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 313;
frmDesign.Height := 480;
frmDesign.Caption := 'frmDesign';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := True;
frmDesign.PixelsPerInch := 96;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 15;
Label1.Top := 20;
Label1.Width := 255;
Label1.Height := 48;
Label1.Caption := 'This Is A Form';
Label1.Font.Color := clWindowText;
Label1.Font.Height := -40;
Label1.Font.Name := 'MS Sans Serif';
Label1.Font.Style := [];
Label1.ParentFont := False;
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 100;
Button1.Top := 360;
Button1.Width := 91;
Button1.Height := 38;
Button1.Caption := 'Start The Script';
Button1.TabOrder := 8;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 110;
Button2.Top := 115;
Button2.Width := 75;
Button2.Height := 31;
Button2.Caption := 'Settings';
Button2.TabOrder := 9;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal', v);
end;

procedure InitForm2;
begin
Settings := CreateForm;
Settings.Left := 250;
Settings.Top := 114;
Settings.Width := 230;
Settings.Height := 381;
Settings.Caption := 'frmDesign';
Settings.Color := clBtnFace;
Settings.Font.Color := clWindowText;
Settings.Font.Height := -11;
Settings.Font.Name := 'MS Sans Serif';
Settings.Font.Style := [];
Settings.Visible := True;
Settings.PixelsPerInch := 96;
Label2 := TLabel.Create(frmDesign);
Label2.Parent := frmDesign;
Label2.Left := 50;
Label2.Top := 29;
Label2.Width := 115;
Label2.Height := 37;
Label2.Caption := 'Settings';
Label2.Font.Color := clWindowText;
Label2.Font.Height := -33;
Label2.Font.Name := 'MS Sans Serif';
Label2.Font.Style := [];
Label2.ParentFont := False;
Button3 := TButton.Create(frmDesign);
Button3.Parent := frmDesign;
Button3.Left := 71;
Button3.Top := 305;
Button3.Width := 75;
Button3.Height := 25;
Button3.Caption := 'Save';
Button3.TabOrder := 8;
end;

procedure SafeInitForm2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm2', v);
end;

procedure ShowFormModal2;
begin
Settings.ShowModal;
end;

procedure SafeShowFormModal2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal2', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.




Next, you need the ButtonClick procedure. (in case you didn't know, it defines what to do when a form button is clicked. You need the following basic code for your main form to close and the script to proceed when the Start button is clicked:

procedure ButtonClick(Sender:TObject);
begin
case Sender of
Button1:
begin
frmDesign.Caption:= frmDesign.Caption + '.';
frmDesign.ModalResult:= mrOk;
end;
end;
We use a case because we will need to add more paramaters for other buttons later.

Then you add to the parameter list for Button1:
Button1.OnClick := @ButtonClick;
Basically, it tells it to refer to the procedure upon being clicked.

Code is now as follows:
program New;
var
frmDesign : TForm;
Settings : TForm;
Label1 : TLabel;
Label2 : TLabel;
Button1 : TButton;
Button2 : TButton;
Button3 : TButton;

procedure SafeInitForm2;forward;
procedure SafeShowFormModal2;forward;

procedure ButtonClick(Sender:TObject);
begin
case Sender of
Button1:
begin
frmDesign.Caption:= frmDesign.Caption + '.';
frmDesign.ModalResult:= mrOk;
end;
end;
end;


procedure InitForm;
begin;
frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 313;
frmDesign.Height := 480;
frmDesign.Caption := 'frmDesign';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := True;
frmDesign.PixelsPerInch := 96;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 15;
Label1.Top := 20;
Label1.Width := 255;
Label1.Height := 48;
Label1.Caption := 'This Is A Form';
Label1.Font.Color := clWindowText;
Label1.Font.Height := -40;
Label1.Font.Name := 'MS Sans Serif';
Label1.Font.Style := [];
Label1.ParentFont := False;
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 100;
Button1.Top := 360;
Button1.Width := 91;
Button1.Height := 38;
Button1.Caption := 'Start The Script';
Button1.TabOrder := 8;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 110;
Button2.Top := 115;
Button2.Width := 75;
Button2.Height := 31;
Button2.Caption := 'Settings';
Button2.TabOrder := 9;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal', v);
end;

procedure InitForm2;
begin
Settings := CreateForm;
Settings.Left := 250;
Settings.Top := 114;
Settings.Width := 230;
Settings.Height := 381;
Settings.Caption := 'frmDesign';
Settings.Color := clBtnFace;
Settings.Font.Color := clWindowText;
Settings.Font.Height := -11;
Settings.Font.Name := 'MS Sans Serif';
Settings.Font.Style := [];
Settings.Visible := True;
Settings.PixelsPerInch := 96;
Label2 := TLabel.Create(frmDesign);
Label2.Parent := frmDesign;
Label2.Left := 50;
Label2.Top := 29;
Label2.Width := 115;
Label2.Height := 37;
Label2.Caption := 'Settings';
Label2.Font.Color := clWindowText;
Label2.Font.Height := -33;
Label2.Font.Name := 'MS Sans Serif';
Label2.Font.Style := [];
Label2.ParentFont := False;
Button3 := TButton.Create(frmDesign);
Button3.Parent := frmDesign;
Button3.Left := 71;
Button3.Top := 305;
Button3.Width := 75;
Button3.Height := 25;
Button3.Caption := 'Save';
Button3.TabOrder := 8;
end;

procedure SafeInitForm2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm2', v);
end;

procedure ShowFormModal2;
begin
Settings.ShowModal;
end;

procedure SafeShowFormModal2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal2', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.

So basically now we have 2 forms and need to link the first to the second using a button. So we go back to ButtonClick. You will now see why the case was important. We add a parameter for Button2, stating that when it is clicked it should display the settings form. Button3, the save button, will be told to close the settings form on being clicked.

Just one error that will occur here and needs to be avoided is that ButtonClick refers to SafeInitForm2 and SafeShowFormModal2, which are further down. We can solve this by putting the following on top of the buttonclick:
procedure SafeInitForm2;forward;
procedure SafeShowFormModal2;forward;

ButtonClick now looks like this:


procedure SafeInitForm2;forward;
procedure SafeShowFormModal2;forward;

procedure ButtonClick(Sender:TObject);
begin
case Sender of
Button1:
begin
frmDesign.Caption:= frmDesign.Caption + '.';
frmDesign.ModalResult:= mrOk;
end;
Button2:
begin
SafeInitForm2;
SafeShowFormModal2;
end;
Button3:
begin
Settings.Caption:=Settings.Caption+'.';
Settings.ModalResult:=mrOk;
end;
end;

The finished product should look like this:
program New;
var
frmDesign : TForm;
Settings : TForm;
Label1 : TLabel;
Label2 : TLabel;
Button1 : TButton;
Button2 : TButton;
Button3 : TButton;

procedure SafeInitForm2;forward;
procedure SafeShowFormModal2;forward;

procedure ButtonClick(Sender:TObject);
begin
case Sender of
Button1:
begin
frmDesign.Caption:= frmDesign.Caption + '.';
frmDesign.ModalResult:= mrOk;
end;
Button2:
begin
SafeInitForm2;
SafeShowFormModal2;
end;
Button3:
begin
Settings.Caption:= Settings.Caption+'.';
Settings.ModalResult:=mrOk;
end;
end;
end;


procedure InitForm;
begin;
frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 313;
frmDesign.Height := 480;
frmDesign.Caption := 'frmDesign';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := True;
frmDesign.PixelsPerInch := 96;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 15;
Label1.Top := 20;
Label1.Width := 255;
Label1.Height := 48;
Label1.Caption := 'This Is A Form';
Label1.Font.Color := clWindowText;
Label1.Font.Height := -40;
Label1.Font.Name := 'MS Sans Serif';
Label1.Font.Style := [];
Label1.ParentFont := False;
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 100;
Button1.Top := 360;
Button1.Width := 91;
Button1.Height := 38;
Button1.Caption := 'Start The Script';
Button1.TabOrder := 8;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 110;
Button2.Top := 115;
Button2.Width := 75;
Button2.Height := 31;
Button2.Caption := 'Settings';
Button2.TabOrder := 9;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal', v);
end;

procedure InitForm2;
begin
Settings := CreateForm;
Settings.Left := 250;
Settings.Top := 114;
Settings.Width := 230;
Settings.Height := 381;
Settings.Caption := 'frmDesign';
Settings.Color := clBtnFace;
Settings.Font.Color := clWindowText;
Settings.Font.Height := -11;
Settings.Font.Name := 'MS Sans Serif';
Settings.Font.Style := [];
Settings.Visible := True;
Settings.PixelsPerInch := 96;
Label2 := TLabel.Create(frmDesign);
Label2.Parent := frmDesign;
Label2.Left := 50;
Label2.Top := 29;
Label2.Width := 115;
Label2.Height := 37;
Label2.Caption := 'Settings';
Label2.Font.Color := clWindowText;
Label2.Font.Height := -33;
Label2.Font.Name := 'MS Sans Serif';
Label2.Font.Style := [];
Label2.ParentFont := False;
Button3 := TButton.Create(frmDesign);
Button3.Parent := frmDesign;
Button3.Left := 71;
Button3.Top := 305;
Button3.Width := 75;
Button3.Height := 25;
Button3.Caption := 'Save';
Button3.TabOrder := 8;
end;

procedure SafeInitForm2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm2', v);
end;

procedure ShowFormModal2;
begin
Settings.ShowModal;
end;

procedure SafeShowFormModal2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal2', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.

I have attached a working example (more sophisticated) from one of my other scripts. Enjoy!

Santa_Clause

2007-06-27 09:46:48

frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 696;
frmDesign.Height := 480;

Much faster way to do it :

SetBounds(250, 114, 696, 480);

frmDesign := CreateForm;
frmDesign.Left := 250;
frmDesign.Top := 114;
frmDesign.Width := 696;
frmDesign.Height := 480;
frmDesign.Caption := 'frmDesign';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := True;
frmDesign.PixelsPerInch := 96;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 222;
Label1.Top := 22;
Label1.Width := 255;
Label1.Height := 48;
Label1.Caption := 'This Is A Form';
Label1.Font.Color := clWindowText;
Label1.Font.Height := -40;
Label1.Font.Name := 'MS Sans Serif';
Label1.Font.Style := [];
Label1.ParentFont := False;
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 287;
Button1.Top := 358;
Button1.Width := 91;
Button1.Height := 50;
Button1.Caption := 'Start The Script';
Button1.TabOrder := 8;
Button1.OnClick := @ButtonClick;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 303;
Button2.Top := 172;
Button2.Width := 75;
Button2.Height := 48;
Button2.Caption := 'Settings';
Button2.TabOrder := 9;
end;

Faster way:

frmDesign := CreateForm;
with frmDesign do
begin
SetBounds(250, 114, 696, 480);
Caption := 'frmDesign';
Color := clBtnFace;
Font.Color := clWindowText;
Font.Name := 'MS Sans Serif';
Visible := False;
PixelsPerInch := 96;
end;

Button1 := TButton.Create(frmDesign);
with Button1 do
begin
Parent := frmDesign;
SetBounds(287, 358, 91, 50);
Caption := 'Start The Script';
TabOrder := 8;
OnClick := @ButtonClick;
end;

Button2 := TButton.Create(frmDesign);
with Button2 do
begin
Parent := frmDesign;
SetBounds(303, 172, 75, 48);
Caption := 'Settings';
TabOrder := 9;
end;
end;

frmDesign.Visible := True;

Should be: frmDesign.Visible := False;

Final Product:

program New;
var
frmDesign : TForm;
Settings : TForm;
Label1 : TLabel;
Button1 : TButton;
Button2 : TButton;
Button3 : TButton;

procedure SafeInitForm2;forward;
procedure SafeShowFormModal2;forward;

procedure ButtonClick(Sender:TObject);
begin
case Sender of
Button1:
begin
frmDesign.Caption:= frmDesign.Caption + '.';
frmDesign.ModalResult:= mrOk;
end;
Button2:
begin
SafeInitForm2;
SafeShowFormModal2;
end;
Button3:
begin
Settings.Caption:= Settings.Caption+'.';
Settings.ModalResult:=mrOk;
end;
end;
end;


procedure InitForm;
begin
frmDesign := CreateForm;
with frmDesign do
begin
SetBounds(250, 114, 696, 480);
Caption := 'frmDesign';
Color := clBtnFace;
Font.Color := clWindowText;
Font.Name := 'MS Sans Serif';
Visible := False;
PixelsPerInch := 96;
end;

Button1 := TButton.Create(frmDesign);
with Button1 do
begin
Parent := frmDesign;
SetBounds(287, 358, 91, 50);
Caption := 'Start The Script';
TabOrder := 8;
OnClick := @ButtonClick;
end;

Button2 := TButton.Create(frmDesign);
with Button2 do
begin
Parent := frmDesign;
SetBounds(303, 172, 75, 48);
Caption := 'Settings';
TabOrder := 9;
end;
end;


procedure InitForm2;
begin
Settings := CreateForm;
with Settings do
begin
SetBounds(250, 114, 696, 480);
Caption := 'Settings';
Color := clBtnFace;
Font.Color := clWindowText;
Font.Name := 'MS Sans Serif';
Visible := False;
PixelsPerInch := 96;
end;
end;


procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal', v);
end;

procedure SafeInitForm2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitForm2', v);
end;

procedure ShowFormModal2;
begin
Settings.ShowModal;
end;

procedure SafeShowFormModal2;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('ShowFormModal2', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.

Overall, nice tutorial(h)