2008-12-19 264 views
3

我經常遇到這個問題,並且正在尋找最佳實踐/方法。我有一個包含數據庫/數據模塊的應用程序,並且希望在啓動時啓動數據庫/數據集,而不必在設計時將「運行時激活」設置爲true(數據庫位置各不相同)。當應用程序啓動時,還可以運行網絡「檢查更新」例程。德爾福:應用程序初始化 - 最佳實踐/方法

鑑於TForm的事件序列,並從不同的試驗和錯誤的結果,我目前使用這種方法:

我使用「全局」記錄在主窗體來存儲所有全局變量設置,有一個稱爲Globals.AppInitialized(boolean)的元素,並在主表單的初始化部分將其設置爲False。

在主窗體的OnShow事件(所有窗體都是在那時創建的),我測試了Globals.AppInitialized;如果它是假的,我運行我的「初始化」的東西,然後通過設置Globals.AppInitialized:= True完成。

這似乎工作得很好,但它是最好的方法?尋找別人的經驗,想法和意見。 TIA ..

+0

從10年前的視頻:https://youtu.be/_PJdZjM2oTw覆蓋這一點。 – Alister 2018-01-15 01:47:37

回答

10

我一般總是關閉自動創建的所有形式除主要形式,可能主要數據模塊。

我學會了你可以做的一個訣竅就是將你的數據模塊添加到你的項目中,允許它自動創建並在你的主窗體之前創建。然後,當你的主窗體被創建時,datamodule的onCreate已經被運行。

如果您的應用程序有一些代碼可以說,請設置控件的焦點(創建時不能執行的操作,因爲它的「不可見」),然後創建用戶消息並將其發佈到您的表單中OnCreate中。消息SHOULD(不保證)會在處理表單消息循環後立即處理。例如:

const 
    wm_AppStarted = wm_User + 101; 


type 
    Form1 = class(tForm) 
    : 
    procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted; 
    end; 

// in your oncreate event add the following, which should result in your wmAppStarted event firing. 
PostMessage(handle,wm_AppStarted,0,0); 

我想不出這是從來沒有處理此消息的單一的時間,但通話的本質在於,它被添加到消息隊列,如果隊列已滿則被「丟棄」。請注意存在邊緣情況。

+3

+1提示禁用表單自動創建。這是Delphi應用程序啓動速度慢的原因之一。另外Windows消息用於延遲處理值得關注。 – mghie 2008-12-20 16:06:12

+0

wmAppStarted過程的主體應該是什麼? – Wojtas 2013-01-11 17:06:13

1

我不確定我明白你爲什麼需要全局變量?現在我編寫所有我的Delphi應用程序,沒有一個全局變量。即使當我使用它們時,我每次應用程序的數量也不會超過幾個。

所以,也許你需要先想想爲什麼你真的需要它們。

+1

總的來說,我避開了它們,但在某些情況下,我發現有幾個變量看起來好像屬於「應用程序本身」。這是一個例子。有時我會在以另一種形式運行一些例程之前檢查它。 也可以將它設置爲表單或DM的「屬性」。 – Jamo 2008-12-19 23:48:53

2

德爾福實際上並沒有像「全局變量」這樣的概念。所有變量的範圍都與它們所在的單位以及使用該單位的其他單位有關。

只是使AppInitialized初始化東西作爲您的數據模塊的一部分。基本上有一個類(或數據模塊),以排除所有非UI的東西

或者你可以(有點像一環,但不是所有的邪惡,這樣的。):

  • 把它從你的閃屏。
  • 在登錄期間執行此操作
  • 在後臺線程中運行「檢查更新」 - 不要強制更新。它有點像Firefox一樣。
+0

謝謝吉姆 - 很有幫助。要點也注意到:「全局變量」的區別。 定時明智的,你看到的任何問題瓦特/從主窗體的OnShow中的事件「炒」初始化的東西? (不過,我喜歡你在數據模塊中容納實際* code *的想法)。 – Jamo 2008-12-20 00:34:31

+0

OnShow中的問題在於,顯示錶單與您想要執行的操作無關。並非所有事情都需要在表單的情況下發生。 – 2008-12-20 01:02:39

+0

感謝您的輸入,Rob! – Jamo 2009-03-28 00:57:49

7

您可能希望在表單創建調用之後和Application.Run之前直接干擾項目源(.dpr文件)。 (甚至更早的情況下)

這是怎麼了,我通常處理這樣的初始化的東西:

... 
Application.CreateForm(TMainForm, MainForm);  
... 
MainForm.ApplicationLoaded; // loads options, etc.. 
Application.Run; 
... 
+3

是的!知道「主表單」不是該程序的入口點並且OnShow不是表單的入口點很重要。 – 2008-12-20 00:59:41

3

我不知道這是有益的,但我的一些應用程序沒有任何形式的自動生成的,即它們在IDE中沒有的MainForm。

與應用對象創建作爲其所有者將自動成爲MainForm的第一種形式。因此,我只能自動創建一個datamodule作爲加載程序,並讓它決定創建何種數據模塊以及以何種順序創建哪些表單。這個datamodule有一個StartUp和ShutDown方法,在dpr的Application.Run周圍被稱爲「括號」。 ShutDown方法可以對關閉過程進行更多的控制。

當你已經設計了不同的「mainforms」爲您的應用程序的不同的使用情況,也可以使用一些配置文件來選擇不同的mainforms這可能是有用的。

0

一招我用的是將一個TTimer主窗體上,時間設定爲像300毫秒,並執行任何初始化(DB登錄,網絡文件副本等)。啓動應用程序立即啓動主窗體並允許任何初始化「事物」發生。用戶無需啓動多個實例思考「Oh..I沒有DBL點擊......我會再次這樣做。」

1

我使用主數據模塊,以檢查是否DB連接正常,並如果沒有,顯示自定義組件的形式建立數據庫連接,然後加載的主要形式有:

Application.CreateForm(TDmMain, DmMain); 

    if DmMain.isDBConnected then 
    begin 
     Application.CreateForm(TDmVisualUtils, DmVisualUtils); 
     Application.CreateForm(TfrmMain, frmMain); 
    end; 

    Application.Run;