2010-09-23 36 views
5

我有我想要執行的功能,我的應用程序完成初始化後,主窗體已創建。我確實有OnShow事件中的代碼(稱爲ProcedureX),但我剛剛注意到它被調用了兩次,因爲OnShow發射兩次。它激發當主程序調用DPR:我的Delphi應用程序完成初始化後,應該在哪裏放置代碼?

Application.CreateForm(TMainForm, MainForm) ; 

爲我所期望的。但在那之後,當我從包括屏幕上的位置的形式INI文件閱讀的東西,我有一個電話:

MainForm.position := poScreenCenter ; 

這樣,它會再次出現火災OnShow中的事件。

我在哪裏可以將我的調用放到ProcedureX中,該調用只能調用一次,哪個需要主表單才能執行?

回答

3

第一次調用過程後,您可以測試並設置一個標誌。像這樣:

type 
    TForm1 = class(TForm) 
    procedure FormShow(Sender: TObject); 
    private 
    FRunOnce: Boolean; 
    public 
    [...] 

[...] 

procedure TForm1.FormShow(Sender: TObject); 
begin 
    if not FRunOnce then begin 
    FRunOnce := True; 
    ProcedureX; 
    end; 
end; 
+0

我按照約定 「與A F前綴田」,所以FRunOnce聽起來更加規範我。不是一個規則,只是一個約定,就像使用T的前綴類名稱一樣。只是讓其他代碼更容易閱讀。 – jachguate 2010-09-24 01:52:14

+0

@jachguate - 當有'F'時,我覺得它應該有一個getter/setter。但那麼這是我的問題,我猜...編輯答案,謝謝指出。 – 2010-09-24 02:10:22

+0

好的,我曾想過這樣做,但似乎是在治療症狀,而不是原因。我想我正在尋找其他一些事件(比如「OnEverythingFinished」),它只被解僱了一次。我所聽到的是沒有!謝謝你的幫助。 FRunOnce就是這樣。 – rossmcm 2010-09-24 02:26:13

4

執行對錶單的正常秩序是:

  • AfterConstruction:當表格並分量與其所有屬性完全創建。
  • OnShow:每當表是準備好展示(是的,造成的任何變化CM_SHOWINGCHANGED可以觸發一個OnShow
  • Activate:每當表把焦點

所以,這取決於你需要在ProcedureX中,AfterConstruction可能就足夠了,而且只執行一次;只需覆蓋它並在inherited之後添加ProcedureX。 將會在OnCreate之後。

如果不是這種情況,您可以從AfterConstruction向您的表單發佈自定義消息,它將排隊並在處理完其他消息後到達您的自定義處理程序。

在這兩種情況下,您都不需要額外的布爾型字段。

+0

那麼使用OnCreate呢? – rossmcm 2010-09-24 03:37:16

+0

這可能是好的。但是AfterConstruction允許在OnCreate中的任何東西之後始終執行ProcedureX ... – 2010-09-24 07:31:12

8

如果您的代碼只需要爲每個表單創建(或每個應用程序運行一次,並且該表單僅在每次應用程序運行時創建一次),請將代碼放置在表單的OnCreate處理程序中。這是它自然去的地方。

現在(因爲D3我認爲)OnCreate在AfterConstruction方法的施工過程結束時觸發。只有當您將OldCreateOrder設置爲True(並且默認情況下它爲False)時,您可能會遇到麻煩,因爲這會使OnCreate在Create構造函數的末尾觸發。

5

@Sertac,

真的不需要FRUNOnce字段;只需執行OnShow = NIL作爲FormShow方法的第一行。如果在事件處理程序的第一行中將事件處理程序字段設置爲NIL,那麼對於一旦表單完全運行時獲得一些代碼並運行起來也非常有用初始化。把你的代碼放在FormActivate方法中,並且作爲方法的第一行,設置OnActivate = NIL。

+4

只有在事件處理程序中沒有別的事情時纔可能執行。但是,如果你在處理程序中有你想要它運行的代碼,只要你f.i.取消隱藏你的表單,你不能讓處理程序無效。 – 2010-09-24 19:30:19

0

@Sertec,

您的代碼將無法正常工作或者如果你想爲每個取消隱藏事件中運行(你還沒有把任何代碼重置frunonce場)。

所以你的方法需要重置frunonce字段,我的需要設置OnShow = FormShow。相同的區別,除了你需要一個額外的領域。

+0

如果我將重置國旗爲什麼我會擁有它?例如:我必須在表單首次顯示後在'OnShow'上運行程序'ShowJustOnce'。每次用戶重新展示表單時,都必須在'OnShow'上運行'UpdateInfo'。因爲'UpdateInfo'不能運行,所以我不能處理這個處理程序。我必須使用該標誌,否則每次重新顯示錶單時都會運行「ShowJustOnce」。 – 2010-09-27 16:29:51

+0

如果您在FormSHow中需要一些運行一次的代碼並且運行多次,那麼是的,您需要一個標誌。這與我們兩個人都在回答的問題並不完全相關,這只是「我怎麼才能讓我的表單在初始顯示時執行一次。」 因此,再次...把它放在FormActivate方法中,並且,作爲方法的第一行,放置「OnActivate:= NIL;」。 如果您希望在每次顯示錶單時運行內容,並且每次實際可見性更改時只運行一次,那麼這是一個不同的問題。 – 2010-09-27 18:44:03

+1

這是相關的,這不是一個不同的問題。我不會建議任何人去刪除他的事件處理程序,因爲我不知道是否有代碼已經存在或不存在,並且也不會在未來...就像'OnShow'一樣,人們也可以在'OnActivate'中使用代碼。例如,我有**代碼,它重新顯示先前隱藏在「OnDeactivate」上的表單。如果我沒有'OnActivate',你會在哪裏建議我再次展示他們? – 2010-09-27 20:22:02

4

您可以在Application.CreateForm後的DPR文件中添加一個過程。 將所有需要在該過程中初始化的代碼。 當您在應用中使用多個表單時效果最佳。

此外,如果初始化需要很多,它讓程序在屏幕上顯示窗體,以便用戶知道該應用程序正在加載。

例子:

PROGRAM MyProgram; 
begin 
    Application.Initialize; 
    Application.CreateForm(TMyForm, MyForm); 
    MyForm.Show; 

    LateInitialize;  <----------- here 

    Application.Run; 
end. 
相關問題