Delphi XE4:关闭内部包表单导致应用程序终止



我的应用程序中有一个test.bpl包,它有一个名为myPackageForm的表单。加载我的包后,当我想关闭myPackageForm时,应用程序将终止。

主要项目初始化:

Application.Initialize;
Application.CreateForm(TMainForm,MainForm);
Application.Run;

主窗体窗体创建:

aPackage := LoadPackage('my bpl path'+test.bpl);
@P_ItemClick := GetProcAddress(aPackage,'ItemClickExcecute');

主窗体按钮点击:

P_ItemClick(Sender);

testPackage命令单位:

Procedure ItemClickExecute(Sender : TObject)
begin
TmyPackageForm.ShowForm();
end;
exports
ItemClickExecute;
end.

myPackagForm有一个类过程来显示它:

Class Procedure TmyPackagForm.ShowForm;
begin
if not Assigned(myPackagForm)
myPackagForm := Application.CreateForm(TmyPackagForm ,myPackagForm );
myPackagForm.Show;
end;

并且在OnClose过程中有:

Release;

作为解决方案,我尝试另一个命令:

myPackagForm := TmyPackagForm.Create(Application); 

创建myPackagForm;

有人知道Delphi XE4中在包上使用CreateForm命令时发生了什么吗?

鲁夫爵士已经掌握了基本知识。通过调用CreateForm创建的第一个表单将成为主表单。当主表单关闭时,应用程序将关闭。

现在,您已经显示了对CreateForm的两个调用。一个在主机应用程序中,另一个在动态加载的包中。很明显,第一个要运行的程序是从主机应用程序中运行的。那么,程序包中的表单如何才能降低应用程序?正如Rufo爵士所说,只有当您的流程中有两个应用程序实例时,才会发生这种情况。

因此,下一个问题是,您的流程中怎么可能有两个应用程序实例?这种情况不应该发生。包的全部目的是允许Delphi单元在不同的模块之间共享。如果您正确构建了应用程序,那么您将只有一个TApplication实例,该实例在主机可执行文件和所有包之间共享。

因此,唯一合理的结论是,您的某个模块不是使用运行时包构建的。例如,主机应用程序可能包括RTL/VCL,它在可执行文件中静态链接。您的软件包链接到RTL/VCL运行时软件包。或者可能是动态加载的包包含静态链接的RTL/VCL。尽管是IIRC,但编译器可以防止这种情况发生。

无论出了什么问题,解决方案都是必须使用运行时包构建所有模块。所有RTL/VCL库必须通过运行时包进行链接,并且不能静态链接。

因此,用TMyPackageForm.Create取代Application.CreateForm只是抑制了一个更广泛的问题。应用程序中只有一个RTL/VCL实例,这一点至关重要。通过在所有模块中使用运行时包来实现这一点。

当然,TMyPackageForm.Create是在包中创建表单的正确方法。我只在主窗体中使用Application.CreateForm。我从不在其他任何地方使用它。但不要仅仅通过从包中删除Application.CreateForm来解决眼前的问题。修复到RTL/VCL的链接。

TApplication.CreateForm不仅创建了一个表单,而且还使该方法创建的第一个表单成为TApplication.MainForm

关闭MainForm会导致关闭应用程序。

更新

您的应用程序中有2个TApplication实例。

  1. 您的正常应用程序
  2. BPL内部

因此,BPL中的表单将成为BPL的主表单。Application并关闭此表单将在主应用程序流程的上下文中执行PostQuitMessage(0),这将迫使整个应用程序退出。

相关内容

  • 没有找到相关文章

最新更新