2013-12-22 59 views
2

我有我的應用程序中的test.bpl包,它有一個名爲myPackageForm的形式。 加載我的包後,當我想關閉myPackageForm,應用程序將終止。德爾福XE4:關閉內部包裝形式導致應用終止

主要項目初始化:

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創建;

任何人都可以知道發生了什麼德爾福XE4與包的CreateForm命令?

+0

沒有任何改變。使用CreateForm創建的第一個表單是主要表單。 –

+0

@David Heffernan你說得對。但是爲什麼我在封裝中使用Application.CreateForm命令時在Delphi7中關閉Package Forms時沒有問題? –

+0

我確信我知道發生了什麼事。我會寫一個答案。 –

回答

3

Rufo爵士已經掌握了基本知識。通過致電CreateForm創建的第一個表格成爲主要表格。當主窗體關閉時,應用程序關閉。

現在,您已向CreateForm顯示了兩個電話。一個在主機應用程序中,另一個在動態加載的包中。看起來很明顯,第一個要運行的是來自主機應用程序。那麼,包裝中的表單如何能夠降低應用程序呢?那麼,就像Rufo爵士所說,只有在你的過程中有兩個應用程序實例才能發生。

所以下一個問題是,在你的過程中如何有兩個應用程序實例?這不應該發生。整個包的重點是允許德爾福單位在不同的模塊之間共享。如果您已經正確構建了應用程序,那麼您將只有一個TApplication的實例在主機可執行文件和所有軟件包之間共享。

因此,唯一合理的結論是,您的模塊之一不是使用運行時軟件包構建的。例如,主機應用程序可能包含RTL/VCL,它們在可執行文件內靜態鏈接。並且您的軟件包鏈接到RTL/VCL運行時軟件包。或者,它可能是動態加載的包,其中包含靜態鏈接的RTL/VCL。儘管IIRC,編譯器可以防止這種情況發生。

無論出現什麼問題,解決方案是您的所有模塊必須使用運行時軟件包構建。所有RTL/VCL庫必須通過運行時軟件包鏈接,並且不得靜態鏈接。

因此,用TMyPackageForm.Create代替Application.CreateForm只是簡單地抑制了一個更廣泛的問題。在應用程序中只有一個RTL/VCL實例是非常重要的。通過在所有模塊中使用運行時包來實現這一目標。

確實如此,TMyPackageForm.Create是在您的軟件包中創建表單的正確方法。我只使用Application.CreateForm作爲主窗體。我從來不會在其他地方使用它。但不要試圖通過從包中刪除Application.CreateForm來解決您的直接問題。修復鏈接到RTL/VCL。

3

TApplication.CreateForm不僅僅只是創建一個表單,而且還會創建這個方法創建的第一個表單TApplication.MainForm

並關閉MainForm結果關閉應用程序。

UPDATE

你有你的應用程序中的2個TApplication實例。

  1. 您的正常應用
  2. 的BPL

所以你的形式BPL內內將成爲您的BPL的MainForm的。 Application並且關閉此表單將在您的主應用程序過程的上下文中執行PostQuitMessage(0),這會強制整個應用程序退出。

+0

調用該包的主項目具有MainForm。你認爲它會改變與內部包的createForm?在舊版本的德爾福(如7.0),它的工作原理! –

+0

應用程序MainForm依賴於由'TApplication.CreateForm'創建的第一個表單。這不是靜態的,取決於它何時被創建。請在您的問題中添加更多代碼,向我們展示何時創建表格 –

+0

感謝Rufo爵士提供的完整答案。但另一個問題是PostQuitMessage是DelphiXE中的一個新性能?因爲在我的包中使用Application.CreateForm命令的Delphi 7中沒有問題。 –