I've followed this: http://docwiki.embarcadero.com/CodeExamples/XE5/en/FMXEmbeddedForm_(Delphi)
and this: https://stackoverflow.com/a/2475810
and this: https://stackoverflow.com/a/26508888
I'm using Delphi 10.3
My final result was: I've created a parent form with a TLayout inside of it where I want the child forms to appear. Next, all my child forms have a TLayout containing all the other components of the form. All forms are dynamically created in runtime and their contents are as well.
For testing purposes I've created the childform inside a button on the main form:
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.CreateForm(TfChild, fChild);
fChild.Layout1.Parent := self.Layout1;
end;
So far so good, all the components of the childform appears on the parent form. Problem is, how to "clear" them afterwards. Sending a self.Close
, on a button on the child form doesn't remove the Layout components from the main form but it closes the child form. Doing a Layout1.Destroy
on the child form's button clears the layout, but I lose acess to my main form's window control buttons (maximize, minimize, exit) and the only way to get that access back is to recreate the child's layout.
This embedded feature I only wanna use for windows and macos OS', for android it won't be necessary so I'm using defs to adjust that.
I feel like I'm not doing this the right way :'(, is there a solution? I just want to dynamically create the components of a child form inside the main form's designated area and have a safe way of clearing those components after that child form is no longer necessary
I made an MRE myself, since you felt you don't need to provide one. In the following Form1
is the main form and Form2
is the child form
When you close a form (e.g. Form2.Close;
), that is NOT the main form, it is not necessarily destroyed. The default close action for a form is caHide
, which only sets its property Visible = False
, which leaves it existing in memory, ready to be called up again.
The components on your child form are still parented to the TLayout
in your main form, so therefore hiding the child form has no influence on the visibility of the components. To correct this you can move the components back from the mainform to the child form:
procedure TForm2.Button1Click(Sender: TObject);
begin
Layout1.Parent := Self; // add this
Self.Close;
end;
Or, you can destroy the child form in its OnClose()
event:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
This works without reparenting the components, because Form2 is still the owner of the components, even though the parent is Form1.