控件的所有者和父项有什么区别? [英] What is the difference between Owner and Parent of a control?

查看:122
本文介绍了控件的所有者和父项有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Delphi VCL控件的两个属性有些好奇。

I am bit curious about the two properties of a Delphi VCL control.

每个组件都有2个属性,分别为 Owner Parent 在运行时。谁能帮助我了解两者之间的区别?以及Windows如何将它们用于显示控件或表单?

Each component has 2 properties as Owner and Parent at runtime. Can anyone help me to understand the difference between both? And how are they used by windows for displaying control or form?

推荐答案

所有者



Owner TComponent 中引入的属性,而 Owner 本身的类型为 TComponent 所有者主要用于管理设计组件的生命周期。也就是说,您放置在表单设计器(或其他设计图面)上的组件的寿命完全由框架管理。 文档说:

Owner

Owner is a property introduced in TComponent, and Owner itself has type TComponent. The Owner is used primarily to manage the lifetime of designed components. That is, components that you place on the form designer (or indeed other design surfaces) and whose lifetime is managed entirely by the framework. The documentation says:


指示负责流式传输和释放该组件的组件。

Indicates the component that is responsible for streaming and freeing this component.

何时创建一个表单后,流框架将解析.dfm文件并实例化其中列出的组件。这些组件通常是用 Owner 指定为表单创建的。

When a form is created, the streaming framework parses the .dfm file and instantiates the components that are listed within. These components are typically created with Owner specified to be the form.

组件寿命的另一端是破坏。销毁组件时,也会销毁它拥有的所有组件。考虑到一个具体示例,在设计时将 TButton 放在 TForm 上。流框架创建按钮,将其 Owner 设置为表单。该表单作为 TComponent 的后代,维护着它拥有的所有组件的列表。销毁表单后,它将遍历该拥有的组件列表并销毁它们。按钮以这种方式被破坏。

At the other end of a component's life is destruction. When a component is destroyed, it also destroys all of the components which it owns. Consider, for the sake of a concrete example, a TButton that sits on a TForm, placed there at design time. The streaming framework creates the button setting its Owner to be the form. The form, as a descendent of TComponent maintains a list of all the components that it owns. When the form is destroyed it walks over that list of owned components and destroys them. The button is destroyed in this manner.

对此有很多细微差别:


  • 组件不需要由表单拥有。例如,在运行时创建的组件由传递给构造函数的任何组件所拥有。

  • 组件不需要拥有者,可以传递 nil 到构造函数。在这种情况下,程序员仍然有责任破坏组件。

  • 在组件的生命周期内可以更改所有权。

  • Components don't need to be owned by the form. For instance, components created at run time are owned by whatever component you pass to the constructor.
  • Components need not have an owner, you can pass nil to the constructor. In this case, the programmer remains responsible for destroying the component.
  • Ownership can be changed during the lifetime of a component.

因为流框架实例化了组件,所以 TComponent 的构造函数被声明为虚拟的:

Because the streaming framework instantiates components, the constructor of TComponent is declared virtual:

constructor Create(AOwner: TComponent); virtual;

如果您是从 TComponent 子代派生的,并且希望将派生的组件放置在设计图面上,则必须尊重该虚拟构造函数。如果在 TComponent 后代中定义一个构造函数,则它必须重写此虚拟构造函数。

If you derived from a TComponent descendent, and you wish for that derived component to be placed on a design surface, then you must respect this virtual constructor. If you define a constructor in your TComponent descendent then it must override this virtual constructor.

值得指出的是Win32具有完全不同的窗口所有者概念,不应与同名的VCL概念混淆。 Windows文档说:

It is worth pointing out that Win32 has a completely different concept of a window's owner, that should not be confused with the VCL concept of the same name. The Windows documentation says:


拥有的Windows

重叠或弹出窗口可以由另一个重叠的窗口或
弹出窗口拥有。拥有所有权在窗口上有几个约束。
-拥有的窗口在z顺序中始终高于其所有者。
-当其所有者被销毁时,系统会自动销毁一个拥有的窗口。
-当拥有者的窗口最小化时,将隐藏拥有的窗口。

An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window. - An owned window is always above its owner in the z-order. - The system automatically destroys an owned window when its owner is destroyed. - An owned window is hidden when its owner is minimized.

只有重叠或弹出窗口可以成为拥有者窗口;子窗口
不能是所有者窗口。

Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window.

在VCL术语中, PopupParent 属性。该属性是在Delphi 7之后引入的,因此您将无法使用。在Delphi 7中,该框架设置了窗口所有者,并且没有提供简单的机制来覆盖该框架的选择。如果确实需要影响窗口所有权,则必须重写 CreateParams 并设置 Params.WndParent 。不幸的是,在Delphi 7中使用VCL处理所有权存在许多问题,有时有必要仔细研究这些有点刺眼的细节。

In VCL terms, this concept is exposed by the PopupParent property. That property was introduced after Delphi 7 so will not be available to you. In Delphi 7, the framework sets the window owner, and gives no easy mechanism to override the framework's choice. If you do need to influence window ownership then you must override CreateParams and set Params.WndParent. Unfortunately, there are a number of problems with the VCL handling of ownership in Delphi 7 and it is sometimes necessary to grub around in these somewhat gory details.

以显示其简单性VCL 文档说:

To show how easy it is to get confused, the VCL documentation says:


WndParent :父窗口的窗口句柄。这与父控件的Handle属性相同。

WndParent: The window handle of the parent window. This is the same as the Handle property of the parent control.

这完全是错误的。对于顶层窗口,这是所有者而不是父级。

This is simply wrong. For a top-level window, this is the owner rather than the parent.

Parent 是在 TControl ,并键入 TWinControl 。此属性广泛用于公开Win32父级和子级控件的概念。 Windows文档说:

Parent is a property defined in TControl and has type TWinControl. This property is used, broadly, to expose the Win32 concept of parent and child controls. The Windows documentation says:


一个窗口可以有一个父窗口。具有父窗口的窗口称为子窗口。父窗口提供用于定位子窗口的坐标系。拥有父窗口会影响窗口外观的各个方面;例如,子窗口将被剪切,以使子窗口的任何部分都不会出现在其父窗口的边界之外。没有父窗口或父窗口是桌面窗口的窗口称为顶层窗口。

A window can have a parent window. A window that has a parent is called a child window. The parent window provides the coordinate system used for positioning a child window. Having a parent window affects aspects of a window's appearance; for example, a child window is clipped so that no part of the child window can appear outside the borders of its parent window. A window that has no parent, or whose parent is the desktop window, is called a top-level window.

实质上,VCL Parent 属性直接映射到Win32父概念。

Essentially, the VCL Parent property maps directly onto the Win32 parent concept.

不过请注意,父项是在 TControl 中定义的。现在, TControl 没有窗口,所以 TControl 并不是Win32的子控件,因为Win32窗口的孩子们自己就是窗户。因此,具有定义的父项 TControl 在VCL的意义上是一个孩子,称为非窗口子控件。这些非窗口控件将自身绘制为父级绘制处理程序的一部分。此类控件的典型示例是 TLabel

Note however, that Parent is defined in TControl. Now, TControl is not windowed, so a TControl is not a child control in the Win32 sense, because a Win32 window's children are themselves windows. So, a TControl with a defined Parent is a child in the VCL sense, known as a non-windowed child control. These non-windowed controls paint themselves as part of their parent's paint handlers. The canonical example of such a control is TLabel.

请注意,当使用窗口控件时,即 TWinControl 后代被破坏,它也破坏了它的所有子代。

Note that when a windowed control, that is a TWinControl descendent, is destroyed, it also destroys all of its children.

A TWinControl 后代可以使用 ControlCount Controls [] 属性枚举其子级。这些枚举窗口儿童和非窗口儿童。

A TWinControl descendent can enumerate its children using the ControlCount and Controls[] properties. These enumerate both windowed and non-windowed children.

这篇关于控件的所有者和父项有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆