TForm.Create(AOwner) ... AOwner ?!?

本文详细介绍了在Delphi中动态创建继承自TControl的窗体对象时,如何选择构造函数中的Owner参数。通过对比nil、self及Application的不同用法,解释了它们各自的应用场景及其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

When creating Delphi objects dynamically, that inherit from TControl, such as a TForm (representing a form/window in Delphi applications), the constructor "Create" expects an "Owner" parameter. Should you use "nil", "self" or "Application"? Find the answer here...

Suppose you have a form TMyForm in an application, and you want to instantiate it at run-time. The TForm class has a "Create" constructor that creates and initializes a new TForm (or descendant) object:

constructor Create(AOwner: TComponent) ;

The AOwner parameter is the owner of the T(Custom)Form object. The owner of the form is responsible for freeing the form (memory allocated by the form) when needed. What's more the form created appears in the Components array of its owner. Second, the form is destroyed automatically when its owner is destroyed. For forms, the latter is usually more important.
Should you provide "nil", "self" or "Application"?

To understand the answer, you first need to know the meaning of "nil", "self" or "Application":

  • nil - specifies that no object owns the form - and therefore a developer (you) is responsible for freeing the created form (by calling myForm.Free when you no longer need the form)
  • Self - specifies the object in which the method is called. If, for example, you are creating a new instance of a TMyForm form from inside a Button's OnClick handler (where this button is placed on a MainForm) - self refers to "MainForm". Thus, when the MainForm is freed - it will also free "MyForm".
  • Application - specifies a global TApplication type variable created when you run your application. "Application" encapsulates your application as well as providing many functions that occur in the background of the program.
Examples:
  1. Modal forms. When creating a form to be displayed modally and freed when the user closes the form, you use "nil" as the owner, as in:

    ~~~~~~~~~~~~~~~~~~~~~~~~~
    var
       myForm : TMyForm;
    begin
       myForm := TMyForm.Create(nil) ;
       try
         myForm.ShowModal;
       finally
         myForm.Free;
       end;
    end;
    ~~~~~~~~~~~~~~~~~~~~~~~~~

  2. Modeless forms. You can use "Application" as the owner here:

    ~~~~~~~~~~~~~~~~~~~~~~~~~
    var
       myForm : TMyForm;
    ...
       myForm := TMyForm.Create(Application) ;
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    Now, when you terminate (exit) the application, the "Application" object will free the "myForm" instance.

    Why and when is TMyForm.Create(Application) NOT recommended? If the form is a modal form (and will be destroyed "right away", as above) you should pass "nil" for the owner.
    You could pass "Application", but the problem with this code is the time delay caused by the notification method being sent to every component and form owned or indirectly owned by the Application. If your application consists of many forms with many components (in the thousands), and the form you're creating has many controls (in the hundreds), the notification delay can be significant.
    Passing nil as the owner instead of Application will cause the form to appear sooner, and will not otherwise affect the code.

  3. When to use "Self"? If the form you need to create is not modal and is not created from the application's main form, if you use Self as the owner, closing the owner will free the created form.

    In general, when creating new form instances, you should not use "Self", use "nil" or "Application" instead (modal/modeless).
    So when to use "self"? "Self" can be used, as the owner, if you don't want the form to outlive its creator.

Warning: if you want to dynamically instantiate a Delphi component and explicitly free it sometime later, always pass nil as the owner. Failure to do so can introduce unnecessary risk, as well as performance and code maintenance problems. Read the article to learn more.

Note: in SDI applications, when a user closes the form (by clicking on the [x] button) the form still exists in the memory - it only gets hidden. In MDI applications, closing an MDI child form only minimizes it.
The OnClose event provides an Action parameter (of the TCloseAction type) you can use to specify what happens when a user attempts to close the form. Setting this parameter to "caFree" will free the form.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值