2014-09-02 81 views
2

我試圖在我的主表單啓動時加載表單。我使用ShowModal。此外,該表單不是自動創建表單,所以我必須先用application.CreateForm創建它。表單在應用程序的FormCreate事件上創建兩次

我的問題是,當我嘗試在FormCreate事件中加載表單時,它會加載表單兩次,當我關閉表單時,我的整個應用程序關閉。

這裏是我的代碼:

procedure Tfrm_main.FormCreate(Sender: TObject); 
var 
    username, password : string; 
begin 
    username := ini.ReadString('user','username',''); 
    if username = '' then 
    begin 
    application.CreateForm(Tfrm_user,frm_user); 
    frm_user.ShowModal; 
    end; 
end; 

我怎樣才能解決這個問題?謝謝。

+5

*「我必須先用application.CreateForm創建它」* - 您不必。使用'frm_user:= Tfrm_user.Create(Application)',你會沒事的。 – 2014-09-02 21:17:52

回答

6

您的問題中的代碼被稱爲Application.CreateForm創建主窗體的調用。然後再次遞歸調用Application.CreateForm,並且導致Tfrm_user實例成爲主要形式。

衆所周知,由Application.CreateForm創建的第一個表單成爲主要表單。在這裏,您可以撥打Application.CreateForm來創建主窗體。但在Application.CreateForm的代碼開始確定VCL認爲是主要形式之前,將執行遞歸調用Application.CreateForm。一直到最後,並且這樣做確定了主要形式是遞歸調用的次要形式。

然後,您將以模態方式顯示輔助表單。稍後,您可以撥打Application.Run,其中顯示了VCL主窗體,您的輔助窗體。再次。然後關閉它。關閉該程序,因爲這是關閉VCL主窗體時發生的情況。

我的建議是在程序的生命中只需撥打Application.CreateForm一次。所以,在OnCreate處理程序創建其它形式是這樣的:

frm_user := Tfrm_user.Create(Application); 

或許讓主要​​形式是所有者。當然可以考慮不使用全局變量frm_user。我會刪除它。

或者另一種選擇是在您撥打電話Application.CreateForm之前以模態方式顯示輔助表單。

+3

IOW,'Application.CreateForm'已經遞歸,內部(2nd)調用首先返回並因此設置主窗體。試圖詳細說明第一段...儘管如此,還是沒有一個確切的描述.. – 2014-09-02 21:26:15

+0

@sertac謝謝,補充說,字可以幫助 – 2014-09-02 21:28:53

5

您被操作順序問題困擾了。

如果你看一下代碼TApplication.CreateForm,你會看到的東西在這個順序發生:

  • 創建適當類型的一種新形式。
  • 如果FMainForm = nil,則將此新窗體賦值給它。
  • 後來,TApplication.Run調用FMainForm.Show;

但是,當程序設置您的主要形式:

  • 它首先創建它,它調用OnFormCreate事件處理程序。然後事件處理程序調用TApplication.CreateForm(在第一個返回之前)創建新表單,看到FMainForm未分配並將此表單分配給它,然後返回。
  • 您的FormCreate然後將此窗體顯示爲模態,然後返回。
  • 事情放鬆一點,我們回到原來的TApplication.CreateForm,它進入下一部分,看到FMainForm已經分配,​​並且不分配它。
  • 然後它返回,TApplication.Run被調用,它顯示了主窗體...錯誤的窗體。

如果你想創建新的形式,調用構造函數來代替:frm_user := Tfrm_user.Create(Application);真的,TApplication.CreateForm應該被使用一次,設立的主要形式。如果你不確切知道它是如何工作的,那可能會給你帶來麻煩。

相關問題