Title: Embedded Forms: an extensive outline!
Question: In the past some people wrote articles and comments about the way to use embedded forms.
Embedded forms as a concept are very useful but articles and comments raised more questions then providing answers.
Answer:
Advantages of using embedded form are clear:
lean and mean on resources, a far better compartimazation of code etc.
The simple way
==============
You have a mainform(MainForm), with
- a container like a panel(MainPanel),
- a sort of menu to choose the form you want to invoke
Asume 6 buttons for invoking the mainform or one of the 5 forms
to embed form1...form5
- a use-list with all the forms to embed (form1,....form5)
Next to that you have some forms (form1, form2...), which are removed from the automatic create list.
The clickevents of all 6 'menu' buttons (mbtn0...mbtn5) point all to MBtn0Click:
||procedure TMainForm.MBtn0Click(Sender: TObject);
||begin
||
|| = free active embedded form (you don't know which is current!)
||
|| if form1 nil then freeandnil(form1)
|| else if form2 nil then freeandnil(form2)
|| else if form3 nil then freeandnil(form3)
|| else if form4 nil then freeandnil(form4)
|| else if form5 nil then freeandnil(form5);
||
|| = create the requested form (I gave the tag of the 'menu' buttons
|| a number 0 for the mainform, 1...5 for the forms to embed.
||
|| case (sender as tbitbtn).Tag of
|| 0: // do nothing: mainform
|| 1:begin
|| form1 := tform1.Create(application);
|| formsetup(form1);
|| end;
|| 2:begin
|| form2 := tform2.Create(application);
|| formsetup(form2);
|| end;
|| 3:begin
|| form2 := tform3.Create(application);
|| formsetup(form3);
|| end;
|| 4:begin
|| form4 := tform4.Create(application);
|| formsetup(form4);
|| end;
|| 5:begin
|| form5 := tform5.Create(application);
|| formsetup(form5);
|| end;
|| end;
||end ;
||
||
|| = The procedure Formsetup does the embedding.
|| The embedding happens through the parent property
||
||
||procedure formsetup(currentform: tform);
||begin
|| with currentform do
|| begin
|| BorderIcons := [];
|| BorderStyle := bsNone;
|| parent := mainform.mainpanel;
|| Align := alClient;
|| visible := true;
|| end;
||end;
||
An alternative (same example)
=============================
An alternative way of using embedded forms is the way Romeo Lefter described in his article. He uses a global variable Currenform (Currentform: Tform) and assigns to this variable the current form to embed.
The elegance of his solution is that you a avoid complex 'freeandnil' sequence. This is the more important if the number of forms to embed grows.
VAR
Currentform : tform;
||procedure TMainForm.MBtn0Click(Sender: TObject);
||begin
||
|| = free active embedded form (you know which is current!)
||
|| if currentform nil then
|| begin
|| currentform.free;
|| unit1.currentform := nil;
|| end;
||
|| = create the requested form (I gave the tag of the 'menu' buttons
|| a number 0 for the mainform, 1...5 for the forms to embed.
||
|| case (sender as tbitbtn).Tag of
|| 0:
|| 1: form1 := tform1.Create(application);
|| 2: form2 := tform2.Create(application);
|| 3: form2 := tform3.Create(application);
|| 4: form4 := tform4.Create(application);
|| 5: form5 := tform5.Create(application);
|| end;
||
|| = The embedding.
|| The embedding happens through the parent property
||
|| with currentform do
|| begin
|| BorderIcons := [];
|| BorderStyle := bsNone;
|| parent := mainform.mainpanel;
|| Align := alClient;
|| visible := true;
|| end;
||end;
||
However, there are some disadvantages.
The first is that coding is a bit more complex. As Romeo Lefeter pointed out in his comment, when you want to change a property of an object on the currently embedded form( e.g. form Form100) you will have to write:
|| If (Currentform = TForm100) then
|| (Currentform as Tform100).MyControl.Myproperty:=MyValue;
in stead of a simple
|| form100.MyControl.Myproperty:=MyValue;
The second disadvantage is a consequence of the first disadvantage: once written, your code cannot easely change from 'normal forms' to embedded form or back. Maybe this is the most serious drawback.