In DELPHI, we usually use Application.CreateForm(TForm2, Form2) and TForm.create to create forms. We can hardly distinguish the difference between the two methods, let alone use TForm.create to generate subforms more often.
However, if you look closely at the VCL source code, you will find that there is a big difference between the two.
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); first call the Create method of TForm1, and then assign it to the Form1 variable. Application.CreateForm(TForm1, Form1); he gets an Instance pointer first, assigns it to Form1, and then to Form1.Create(Application). The difference between Tform1.create is that in the OnCreate event of TForm1, we can use the variable Form1.
Never underestimate the difference. For example, your program has multiple forms, each subform is generated dynamically through Tform1.create when needed. If you want to assign text attribute to Edit1 on the form in the FormOnCreate event, you can't use form1.edit1.text: ='wudi_1982', you can use self.edit1.text or edit1.text directly. At this point, you might think that you can use edit1.text directly. Why should I write more form1.edit1.text? In addition to understanding the difference between the two, the more important thing is that if you have a function in your program, which is not written in the form class, this function calls information on the form, and when initialization, you must call it. If you do not understand the reason, you may have to debug this problem for a long time. I will not write an example about this. In the DEMO program of DELPHI, there is another one about ListView, which has a similar situation, except that DEMO program has only one form, not Tform.create. If you are interested, you can add that routine to an existing project, and then generate it in two different ways, you will find the problem.
II. Closing of Forms
Normally, we use the close method or click the close button in the upper right corner of the form to close the neutral form in the program. So for VCL forms, does it really "close"? By default, the answer is No. Looking at the VCL source code, you will find that the closure can only be considered as hiding. As for how to test, I think you know.
To completely close the form and release resources, call its free method (a common method for schema forms) or set Action: = caFree (a common method for schemaless forms) in an onclose event, if the form passes and assigns itself nil. I won't say much about why you do Form1: = nil by hand.
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;
Reproduced in: https://my.oschina.net/cookblack/blog/621389