18

I'm working on a module which consists of a page control. By default, this page control (TPageControl) shouldn't have any tab sheets (TTabSheet), but upon initialization, it should dynamically insert these pages and embed a form inside of it.

The issue comes with knowing how to insert a tab sheet into the page control. How do I create this? And once it's created, along with the forms inside each one, how do I iterate through them to destroy the forms?

Ken White
  • 123,280
  • 14
  • 225
  • 444
Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327

3 Answers3

38

1. How to dynamically create a tab sheet ?

procedure TForm1.Button1Click(Sender: TObject);
var
  TabSheet: TTabSheet;
begin
  TabSheet := TTabSheet.Create(PageControl1);
  TabSheet.Caption := 'New Tab Sheet';
  TabSheet.PageControl := PageControl1;
end;

2. How to embed a form inside of a tab sheet ?

To insert a form inside of a tab sheet use simply a parent change:

Form2.Parent := TabSheet;
Form2.Show;

3. Will I need to manually free the forms embedded into a tab sheet when destroying it ?

No, it is enough to free a tab sheet. In case when the forms will have a tab sheet, or to be more precise, the TWinControl as their Parent, that parent will take care of their release when freeing itself.

TLama
  • 75,147
  • 17
  • 214
  • 392
  • 1
    And should I worry about freeing the tab sheet? And how would I go about making sure the form gets free'd? – Jerry Dodge Sep 02 '12 at 03:40
  • You can free tab sheets, that's perfectly safe. About those forms parented to tab sheets, they are released when you free the tab sheet. – TLama Sep 02 '12 at 03:57
  • 3
    Isn't it ownership rather than parent/child that controls lifetime? – David Heffernan Sep 02 '12 at 06:50
  • 2
    @David, well, I'm relying on this for a long time but it's the result of debugging. There's the (here simplified) loop like this `while ControlCount <> 0 do Controls[ControlCount-1].Destroy;` in `TWinControl` destructor. That loop causes all children to die, so now I'm really confused if all those answers, saying that the owner and only owner takes care of component destruction are correct, since it seems that parentship does the same. – TLama Sep 02 '12 at 12:01
  • 4
    @TLama [Yes (see here)](http://stackoverflow.com/questions/7075637/delphi-ownership-confusion/7077151#7077151), parentship takes care of child destruction, too. – Ondrej Kelle Sep 02 '12 at 13:47
  • Looks like you've answered my question. – David Heffernan Sep 02 '12 at 15:29
3

David Heffernan is right.

Form2.Parent := TabSheet;
Form2.Show;

This code just means Form2's parent is TabSheet, not it's owner.

You can create the form like this:

Form2 := TForm2.Create(nil);

and then free it by yourself. or you can create a form like this:

Form2 := TForm2.Create(Form1);

Form1 is the owner of Form2, and it will automatically free Form2 when itself is freed.

TLama
  • 75,147
  • 17
  • 214
  • 392
Geen_Nuar
  • 31
  • 1
  • 3
    Well, then try what happens when you create a form, set its parent to tab sheet, free the tab sheet and then try to free the form. I'm not voting here, just saying. – TLama Sep 02 '12 at 11:26
0

I do the same in a project that has over 100 forms (1 per DLL). I set the FormClose Action to caFree - some customers run this product 24x, for a couple years without issue. Only leaks found are in Borland's VCL. Project started in D5, then D7, and we are in the process of porting to Alexandria 11.2 (D35 I think). I may port to Lazarus and migrate to Mac and Linux desktop users.

Ozz Nixon
  • 159
  • 1
  • 8