In-depth study of VCL source code DELPHI form creation and closure

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

Keywords: Delphi Python Attribute

Added by radman08 on Sat, 15 Jun 2019 01:47:16 +0300