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

Delphi XE4:关闭内部包表单导致应用程序终止,delphi,package,delphi-xe4,terminate,bpl,Delphi,Package,Delphi Xe4,Terminate,Bpl,我的应用程序中有一个test.bpl包,它有一个名为myPackageForm的表单。 加载包后,当我想关闭我的PackageForm时,应用程序将终止 主要项目初始化: Application.Initialize; Application.CreateForm(TMainForm,MainForm); Application.Run; 主窗体窗体创建: aPackage := LoadPackage('my bpl path'+test.bpl); @P_ItemClick := GetP

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

主要项目初始化:

Application.Initialize;
Application.CreateForm(TMainForm,MainForm);
Application.Run;
主窗体窗体创建:

aPackage := LoadPackage('my bpl path'+test.bpl);
@P_ItemClick := GetProcAddress(aPackage,'ItemClickExcecute');
主窗体按钮单击:

p_项目点击(发送方)

testPackage命令sunit:

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

exports
  ItemClickExecute;

end.
MyPackageForm有一个类过程来显示它:

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

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

myPackagForm := TmyPackagForm.Create(Application); 
以我的包装形式创作

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

不仅要创建一个表单,而且要将使用此方法创建的第一个表单设置为

关闭主窗体将导致关闭应用程序

更新

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

  • 您的正常应用程序
  • BPL内部

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

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

    现在,您已经显示了对
    CreateForm
    的两个调用。一个在主机应用程序中,一个在动态加载的包中。显然,第一个运行的应用程序来自主机应用程序。那么,包中的表单如何使应用程序停止运行呢?正如鲁福爵士所说,只有当您的流程中有两个应用程序实例时,才会发生这种情况

    因此,下一个问题是,在您的流程中如何有两个应用程序实例?这不应该发生。包的整个要点是允许在不同模块之间共享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的链接。

    调用包的主项目有一个MainForm。您认为内部包中的createForm会改变它吗?在旧版本的delphi(如7.0)中,它可以工作!应用程序主窗体取决于由
    TApplication.CreateForm
    创建的第一个窗体。这不是静态的,取决于创建它的时间而不是位置。请在您的问题中添加更多代码,以向我们展示表格的创建时间感谢鲁福爵士的完整回答。但另一个问题是PostQuitMessage是DelphiXE中的一种新性能?因为我在Delphi7中对包中的Application.CreateForm命令没有任何问题。没有任何更改。用CreateForm创建的第一个窗体是主窗体。@大卫·赫弗南你说得对。但为什么我在Delphi7中使用Application.CreateForm命令关闭包表单时没有问题呢?我很确定我知道发生了什么。我会写一个答案。