当软件启动时,我们希望从配置文件中加载参数,然后用这些参数,改变窗口的状态大小,或者组件的属性。
通常的做法是在 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.