一、窗體的建立
在DELPHI中,我們通常使用Application.CreateForm(TForm2, Form2)和TForm.create來創建窗體,我們幾乎無法區別這兩種方法差異,更何況,我們更多的時候都是在使用TForm.create來生成子窗體。
不過,仔細觀察VCL源碼,你會發現,其實兩者區別很大。
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance);
TComponent(Reference) := Instance;
try
Instance.Create(Self);
except
TComponent(Reference) := nil;
raise;
end;
if (FMainForm = nil) and (Instance is TForm) then
begin
TForm(Instance).HandleNeeded;
FMainForm := TForm(Instance);
end;
end;
constructor TCustomForm.Create(AOwner: TComponent);
begin
GlobalNameSpace.BeginWrite;
try
CreateNew(AOwner);
if (ClassType <> TForm) and not (csDesigning in ComponentState) then
begin
Include(FFormState, fsCreating);
try
if not InitInheritedComponent(Self, TForm) then
raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
finally
Exclude(FFormState, fsCreating);
end;
if OldCreateOrder then DoCreate;
end;
finally
GlobalNameSpace.EndWrite;
end;
end;
Form1 := TForm1.Create(Application); 是先調用TForm1的Create方法, 然後賦值 給Form1變量。而Application.CreateForm(TForm1, Form1); 他會先得到一個Instance的指針, 把這個指針賦值給Form1, 然後是Form1.Create(Application). 這Tform1.create的區別在于, 在TForm1的OnCreate事件中, 我們可以使用Form1這個變量。
千萬不要小瞧這點區別。例如你的程序有多個窗體,各個子窗體都是在需要的時候通過Tform1.create動態生成的,你想在FormOnCreate事件中對窗體上的edit1賦值text屬性,那麽你不能直接使用Form1.edit1.text := 'wudi_1982',你可以使用self.edit1.text 或者直接使用edit1.text。此時,你可能會想,可以直接用edit1.text,我爲什麽要多寫form1.edit1.text呢?這裏除了了解兩者的區別,更重要的在于,如果你的程序中有一個函數,函數並非寫在窗體類中,此函數調用了form上的信息,而在初始化的時候,你又必須調用它,如果不明白此中道理,可能就這個問題,就要讓你調試好長時間,關于這方面的例子我就不寫了。在DELPHI的DEMO程序中,又一個關于ListView的,其中就有類似的情況,只不過那個DEMO程序只有一個窗體,用不到Tform.create,如果有興趣,你可以把那個例程添加到一個已存在的工程中,然後用兩種不同的方法生成,你就會發現問題了。
二、窗體的關閉
通常情況下,我們對于程序中子窗體的關閉,大多是使用close方法或者直接點擊窗體右上角的關閉按鈕。那麽對于VCL的窗體,它真的“關閉”了嗎?在默認情況下,答案是否定的。觀察VCL源碼,你會發現,那個關閉只能算做隱藏。至于怎麽測試,我想你知道。
要徹底關閉窗體並釋放資源,就要調用他的free方法(模式窗體的常用辦法),或者在onclose事件中,設置Action := caFree(無模式窗體的常用辦法),如果窗體還要通過並且將自身賦值爲nil。關于爲什麽手動做form1 := nil的操作,我這裏就不多說了,
TCloseAction = (caNone, caHide, caFree, caMinimize);
procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then
begin
if FormStyle = fsMDIChild then
if biMinimize in BorderIcons then
CloseAction := caMinimize else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else Release;
end;
end;
創建良好設計的代碼(基于Delphi/VCL)我們平時都會寫很多代碼,爲公司,爲自己或者爲朋友。有時,爲了驗證自己的一個想法,或學習某一個技術,會寫一些試驗性的代碼。這樣的代碼的生命周期很短,基本不需要維護,隨意寫一下就可以。但是,當你真正要完成...查看完整版>>
創建良好設計的代碼(基于Delphi/VCL)
WIN32下DELPHI中的多線程【深入VCL源碼】(一)線程的基礎知識 線程的組成。線程有兩部分組成。 1、一個是線程的內核對象,操作系統用它來對線程實施管理。內核對象也是系統用來存放線程統計信息的地方。 2、另一個是線程堆棧,它用于維護線程在執行...查看完整版>>
WIN32下DELPHI中的多線程【深入VCL源碼】(一)
爲什麽創建VCL for .NET? -- Delphi編譯器架構師撰文爲什麽創建VCL for .NET?Why VCL for .NET 作者:Danny Thorpe 翻譯:Bear 摘要:爲什麽Borland創建VCL for .NET?什麽時候你該使用VCL for .NET而不是.NET系統本身的的Windows Forms框架?Delphi 8 for .NET在Del...查看完整版>>
爲什麽創建VCL for .NET? -- Delphi編譯器架構師撰文
爲什麽創建VCL for .NET? -- Delphi編譯器架構師撰文爲什麽創建VCL for .NET? 作者:Danny Thorpe 翻譯:Bear 摘要:爲什麽Borland創建VCL for .NET?什麽時候你該使用VCL for .NET而不是.NET系統本身的的Windows Forms框架?Delphi 8 for .NET在Delphi社群中引起了極...查看完整版>>
爲什麽創建VCL for .NET? -- Delphi編譯器架構師撰文
Delphi下用Windows API創建窗體program delphi;uses windows, messages;const hellostr=Hello World!;{$R delphi.res}//窗口消息處理函數.function MyWinProc(hWnd:THandle;uMsg:UINT;wParam,lParam:Cardinal):Cardinal;export;std...查看完整版>>
Delphi下用Windows API創建窗體