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

时间:2013-12-22 06:36:18

标签: delphi package delphi-xe4 terminate bpl

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

主要项目初始化:

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

MainForm FormCreate:

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

MainForm ButtonClick:

P_ItemClick(Sender);

testPackage CommandsUnit:

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;

有人可以通过包上的CreateForm命令知道 Delphi XE4 中发生了什么吗?

2 个答案:

答案 0 :(得分:3)

TApplication.CreateForm不仅可以创建表单,还可以使此方法创建的第一个表单为TApplication.MainForm

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

<强>更新

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

  1. 您的正常申请
  2. 在BPL内部
  3. 因此,您在BPL中的表单将成为您的BPL的主要表单。Application并关闭此表单将在您的主应用程序进程的上下文中执行PostQuitMessage(0),这会强制整个应用程序退出

答案 1 :(得分:3)

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

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

接下来的问题是,您的流程中如何有两个应用程序实例?这不应该发生。包的整个要点是允许Delphi单元在不同模块之间共享。如果您已正确构建应用程序,则只有一个TApplication实例在主机可执行文件和所有软件包之间共享。

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

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

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

肯定是TMyPackageForm.Create是在包中创建表单的正确方法。我只使用Application.CreateForm作为主表单。我从来没有在其他地方使用它。但是,不要试图通过从包中删除Application.CreateForm来解决您的直接问题。修复链接到RTL / VCL。