Delphi 10.3 在另一个FMX 窗体中创建FMX 窗体关闭错误
Delphi 10.3 Creating FMX forms inside another FMX form close error
我关注了这个:http://docwiki.embarcadero.com/CodeExamples/XE5/en/FMXEmbeddedForm_(Delphi)
还有这个:
还有这个:
我正在使用 Delphi 10.3
我的最终结果是:我创建了一个 parent 表单,里面有一个 TLayout,我希望 child 表单出现在其中。接下来,我所有的 child 表单都有一个包含表单所有其他组件的 TLayout。所有表单都是在运行时动态创建的,它们的内容也是如此。
出于测试目的,我在主窗体的按钮内创建了 child窗体:
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.CreateForm(TfChild, fChild);
fChild.Layout1.Parent := self.Layout1;
end;
到目前为止一切顺利,child 表单的所有组件都出现在 parent 表单上。问题是,之后如何 "clear" 他们。在 child 表单上的按钮上发送 self.Close
不会从主表单中删除布局组件,但会关闭 child 表单。在 child 窗体的按钮上执行 Layout1.Destroy
会清除布局,但我无法访问主窗体的 window 控制按钮(最大化、最小化、退出)以及获得该访问权限的唯一方法返回是重新创建 child 的布局。
我只想将此嵌入式功能用于 windows 和 macos OS',对于 android 则没有必要,因此我正在使用 defs 对其进行调整。
我觉得我这样做的方式不对:'(,有解决办法吗?我只想在主窗体的指定区域内动态创建一个 child 窗体的组件,并拥有在不再需要 child 表单后清除这些组件的安全方法
我自己做了一个MRE,因为你觉得你不需要提供。下面Form1
是主窗体,Form2
是子窗体
当您关闭一个不是主窗体的窗体(例如 Form2.Close;
)时,它不一定会被销毁。窗体的默认关闭操作是 caHide
,它只设置它的 属性 Visible = False
,它保留在内存中,准备再次调用。
子窗体上的组件仍然是主窗体中 TLayout
的父级,因此隐藏子窗体不会影响组件的可见性。要更正此问题,您可以将组件从主窗体移回子窗体:
procedure TForm2.Button1Click(Sender: TObject);
begin
Layout1.Parent := Self; // add this
Self.Close;
end;
或,可以在其OnClose()
事件中销毁子窗体:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
无需重新设置组件的父级即可工作,因为 Form2 仍然是组件的所有者,即使父级是 Form1。
/* It works on C++ Builder
the main form has a layout component called LayoutContainer
and the child form has a main LayoutClient which contains all objects*/
//code in main form
#include "UChild.h"
void __fastcall TFmMain::Item1Click(TObject *Sender)
{
TFmChild *FmChild;
TLayout *LyChild;
FmChild = new TFmChild(Application);
LyChild = dynamic_cast<TLayout *> (FmChild->FindComponent("LayoutClient"));
LayoutContainer->AddObject(LyChild);
}
//---------------------------------------------------------------------------
//child form has a button bnBack1
//this code is in child form
void __fastcall TFmBoletos::bnBack1Click(TObject *Sender)
{
LayoutClient->Parent = this;
this->Close();
}
我关注了这个:http://docwiki.embarcadero.com/CodeExamples/XE5/en/FMXEmbeddedForm_(Delphi)
还有这个:
还有这个:
我正在使用 Delphi 10.3
我的最终结果是:我创建了一个 parent 表单,里面有一个 TLayout,我希望 child 表单出现在其中。接下来,我所有的 child 表单都有一个包含表单所有其他组件的 TLayout。所有表单都是在运行时动态创建的,它们的内容也是如此。
出于测试目的,我在主窗体的按钮内创建了 child窗体:
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.CreateForm(TfChild, fChild);
fChild.Layout1.Parent := self.Layout1;
end;
到目前为止一切顺利,child 表单的所有组件都出现在 parent 表单上。问题是,之后如何 "clear" 他们。在 child 表单上的按钮上发送 self.Close
不会从主表单中删除布局组件,但会关闭 child 表单。在 child 窗体的按钮上执行 Layout1.Destroy
会清除布局,但我无法访问主窗体的 window 控制按钮(最大化、最小化、退出)以及获得该访问权限的唯一方法返回是重新创建 child 的布局。
我只想将此嵌入式功能用于 windows 和 macos OS',对于 android 则没有必要,因此我正在使用 defs 对其进行调整。
我觉得我这样做的方式不对:'(,有解决办法吗?我只想在主窗体的指定区域内动态创建一个 child 窗体的组件,并拥有在不再需要 child 表单后清除这些组件的安全方法
我自己做了一个MRE,因为你觉得你不需要提供。下面Form1
是主窗体,Form2
是子窗体
当您关闭一个不是主窗体的窗体(例如 Form2.Close;
)时,它不一定会被销毁。窗体的默认关闭操作是 caHide
,它只设置它的 属性 Visible = False
,它保留在内存中,准备再次调用。
子窗体上的组件仍然是主窗体中 TLayout
的父级,因此隐藏子窗体不会影响组件的可见性。要更正此问题,您可以将组件从主窗体移回子窗体:
procedure TForm2.Button1Click(Sender: TObject);
begin
Layout1.Parent := Self; // add this
Self.Close;
end;
或,可以在其OnClose()
事件中销毁子窗体:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
无需重新设置组件的父级即可工作,因为 Form2 仍然是组件的所有者,即使父级是 Form1。
/* It works on C++ Builder
the main form has a layout component called LayoutContainer
and the child form has a main LayoutClient which contains all objects*/
//code in main form
#include "UChild.h"
void __fastcall TFmMain::Item1Click(TObject *Sender)
{
TFmChild *FmChild;
TLayout *LyChild;
FmChild = new TFmChild(Application);
LyChild = dynamic_cast<TLayout *> (FmChild->FindComponent("LayoutClient"));
LayoutContainer->AddObject(LyChild);
}
//---------------------------------------------------------------------------
//child form has a button bnBack1
//this code is in child form
void __fastcall TFmBoletos::bnBack1Click(TObject *Sender)
{
LayoutClient->Parent = this;
this->Close();
}