當軟件啟動時,我們希望從配置文件中加載參數,然后用這些參數,改變窗口的狀態大小,或者組件的屬性。
通常的做法是在 TForm 的 OnCreate 事件中或者 OnFirstShow 事件中執行這些任務。 但是,但某些改變窗口的語句,
在這些事件中執行時,是會發生沖突的。比如:在 OnShow 事件中,不能去改變 visiable 屬性。因此,我們需要一個真正解除耦合的事件,
此處將其定義為 DeAfterCreate , 即稱為 解除耦合的 AfteCreate 事件。 同樣地,也實現了一個 DeClose 事件。
1 unit uFrmDeBase; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 Vcl.Controls, Vcl.Forms, Vcl.Dialogs; 8 9 type 10 TFrmDeBase = class(TForm) 11 procedure FormShow(Sender: TObject); 12 private 13 { Private declarations } 14 FNotFirstShow: Boolean; // 取名為這樣是利用默認值為 false, 減少去 create 事件中去賦值。 15 protected 16 procedure DeAfterCreate(); virtual; 17 procedure DeClose(); 18 public 19 { Public declarations } 20 end; 21 22 implementation 23 24 {$R *.dfm} 25 26 procedure TFrmDeBase.DeAfterCreate; 27 begin 28 end; 29 30 procedure TFrmDeBase.DeClose; 31 begin 32 TThread.CreateAnonymousThread( 33 procedure 34 begin 35 TThread.Queue(nil, 36 procedure 37 begin 38 Self.Close; 39 end); 40 end).Start; // 創建一個匿名線程 41 // 在匿名線程中,再排隊執行主線程時空的代碼 42 end; 43 44 procedure TFrmDeBase.FormShow(Sender: TObject); 45 begin 46 // 我們利用 FirstOnShow 這個時機,創造一個解除耦合的 DeAfterCreate 事件。 47 if not FNotFirstShow then 48 begin 49 FNotFirstShow := true; 50 TThread.CreateAnonymousThread( 51 procedure 52 begin 53 TThread.Queue(nil, 54 procedure 55 begin 56 DeAfterCreate; 57 end); 58 59 end).Start; 60 end; 61 end; 62 63 end.
1 unit uFrmMain; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uFrmDeBase, Vcl.StdCtrls; 8 9 type 10 TFrmMain = class(TFrmDeBase) 11 Button1: TButton; 12 procedure Button1Click(Sender: TObject); 13 private 14 { Private declarations } 15 protected 16 procedure DeAfterCreate(); override; 17 public 18 { Public declarations } 19 end; 20 21 var 22 FrmMain: TFrmMain; 23 24 implementation 25 26 {$R *.dfm} 27 { TFrmMain } 28 29 procedure TFrmMain.Button1Click(Sender: TObject); 30 begin 31 inherited; 32 DeClose; 33 // 你可以在各種事件中(OnClose事件中除外),執行 DeClose 函數。 34 // 不必擔心耦合問題。 35 // 這個相當於“延時執行” Close 動作。 36 // *** 37 // 如果沒有解除耦合,就可能在 Close 動作之后,返回到別的事件函數中,執行了比如設置組件信息操作。導致出錯。 38 // “延時執行”,相當於此函數不在“任何函數中調用的。“完全獨立”。 39 // 解除耦合,是很重要的編程思維,可以讓多任務,復雜關系調用簡單化。 40 end; 41 42 procedure TFrmMain.DeAfterCreate; 43 begin 44 // 此處是解耦合的 AfterCreate 事件 45 // 在此時,窗口已經真正創建完畢 46 // 可以在此處加載各種參數 47 // 可以設置窗口大小,位置,等信息而不會發生錯誤。 48 /// ***************** 49 // 比如:你直接在 OnShow / OnCreate 等其它事件中 50 // 因為沒有解除耦合,下面的功能會發生錯誤 51 self.Position := poScreenCenter; 52 self.Visible := false; 53 self.Visible := true; 54 self.BringToFront; 55 end; 56 57 end.