深入VCL源碼研究DELPHI窗體的創建和關閉

一、窗體的建立

在DELPHI中,我們通常使用Application.CreateForm(TForm2, Form2)和TForm.create來創建窗體,我們幾乎無法區別這兩種方法差異,更何況,我們更多的時候都是在使用TForm.create來生成子窗體。

不過,仔細觀察VCL源碼,你會發現,其實兩者區別很大。

深入VCL源碼研究DELPHI窗體的創建和關閉
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);

深入VCL源碼研究DELPHI窗體的創建和關閉
var

深入VCL源碼研究DELPHI窗體的創建和關閉
Instance: TComponent;

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
Instance := TComponent(InstanceClass.NewInstance);

深入VCL源碼研究DELPHI窗體的創建和關閉
TComponent(Reference) := Instance;

深入VCL源碼研究DELPHI窗體的創建和關閉
try

深入VCL源碼研究DELPHI窗體的創建和關閉
Instance.Create(Self);

深入VCL源碼研究DELPHI窗體的創建和關閉
except

深入VCL源碼研究DELPHI窗體的創建和關閉
TComponent(Reference) := nil;

深入VCL源碼研究DELPHI窗體的創建和關閉
raise;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
if (FMainForm = nil) and (Instance is TForm) then

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
TForm(Instance).HandleNeeded;

深入VCL源碼研究DELPHI窗體的創建和關閉
FMainForm := TForm(Instance);

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉

深入VCL源碼研究DELPHI窗體的創建和關閉

深入VCL源碼研究DELPHI窗體的創建和關閉
constructor TCustomForm.Create(AOwner: TComponent);

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
GlobalNameSpace.BeginWrite;

深入VCL源碼研究DELPHI窗體的創建和關閉
try

深入VCL源碼研究DELPHI窗體的創建和關閉
CreateNew(AOwner);

深入VCL源碼研究DELPHI窗體的創建和關閉
if (ClassType <> TForm) and not (csDesigning in ComponentState) then

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
Include(FFormState, fsCreating);

深入VCL源碼研究DELPHI窗體的創建和關閉
try

深入VCL源碼研究DELPHI窗體的創建和關閉
if not InitInheritedComponent(Self, TForm) then

深入VCL源碼研究DELPHI窗體的創建和關閉
raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);

深入VCL源碼研究DELPHI窗體的創建和關閉
finally

深入VCL源碼研究DELPHI窗體的創建和關閉
Exclude(FFormState, fsCreating);

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
if OldCreateOrder then DoCreate;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
finally

深入VCL源碼研究DELPHI窗體的創建和關閉
GlobalNameSpace.EndWrite;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉

深入VCL源碼研究DELPHI窗體的創建和關閉

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的操作,我這裏就不多說了,

深入VCL源碼研究DELPHI窗體的創建和關閉
TCloseAction = (caNone, caHide, caFree, caMinimize);

深入VCL源碼研究DELPHI窗體的創建和關閉

深入VCL源碼研究DELPHI窗體的創建和關閉
procedure TCustomForm.Close;

深入VCL源碼研究DELPHI窗體的創建和關閉
var

深入VCL源碼研究DELPHI窗體的創建和關閉
CloseAction: TCloseAction;

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
if fsModal in FFormState then

深入VCL源碼研究DELPHI窗體的創建和關閉
ModalResult := mrCancel

深入VCL源碼研究DELPHI窗體的創建和關閉
else

深入VCL源碼研究DELPHI窗體的創建和關閉
if CloseQuery then

深入VCL源碼研究DELPHI窗體的創建和關閉
begin

深入VCL源碼研究DELPHI窗體的創建和關閉
if FormStyle = fsMDIChild then

深入VCL源碼研究DELPHI窗體的創建和關閉
if biMinimize in BorderIcons then

深入VCL源碼研究DELPHI窗體的創建和關閉
CloseAction := caMinimize else

深入VCL源碼研究DELPHI窗體的創建和關閉
CloseAction := caNone

深入VCL源碼研究DELPHI窗體的創建和關閉
else

深入VCL源碼研究DELPHI窗體的創建和關閉
CloseAction := caHide;

深入VCL源碼研究DELPHI窗體的創建和關閉
DoClose(CloseAction);

深入VCL源碼研究DELPHI窗體的創建和關閉
if CloseAction <> caNone then

深入VCL源碼研究DELPHI窗體的創建和關閉
if Application.MainForm = Self then Application.Terminate

深入VCL源碼研究DELPHI窗體的創建和關閉
else if CloseAction = caHide then Hide

深入VCL源碼研究DELPHI窗體的創建和關閉
else if CloseAction = caMinimize then WindowState := wsMinimized

深入VCL源碼研究DELPHI窗體的創建和關閉
else Release;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉
end;

深入VCL源碼研究DELPHI窗體的創建和關閉

深入VCL源碼研究DELPHI窗體的創建和關閉

創建良好設計的代碼(基于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創建窗體
 
Delphi下用WindowsAPI創建窗體
// Delphi 下調用Windows API 創建窗體. //// 模板-------BY Hottey 2004-4-13-0:18 //// 作者網站: // program delphi;uses windows, messages;const hellostr='Hello World!';{$R delphi....查看完整版>>Delphi下用WindowsAPI創建窗體
 
深入VCL理解BCB的消息機制2
  重載TControl的WndProc方法還是先談談VCL的繼續策略。VCL中的繼續鏈的頂部是TObject基類。一切的VCL組件和對象都繼續自TObject。打開BCB幫助查看TControl的繼續關系:TObject->TPersistent->TComponent-&g...查看完整版>>深入VCL理解BCB的消息機制2
 
如何將界面代碼和功能代碼分離(基于Delphi/VCL)
摘要:如何將界面代碼和功能代碼分離(基于Delphi/VCL)asp/sunidoc.asp">東日文檔 很多朋友看了上次我寫的“創建良好設計的代碼(基于Delphi/VCL)”後,對我說感覺上可以接受其中的觀點,但似乎說得太簡...查看完整版>>如何將界面代碼和功能代碼分離(基于Delphi/VCL)
 
《Delphi高手突破》節選--脫離VCL的Windows程序
我知道,朋友們等待這本書很久了,好多朋友都發Email來問。出版社現在說,10月中旬可以上市。上市最快的,應該是網絡上的銷售,然後,常規渠道來說,北京應該比其他區域快。在此,再貼出一段節選。書的支持網站:htt...查看完整版>>《Delphi高手突破》節選--脫離VCL的Windows程序
 
 
回到王朝網路移動版首頁