我对Delphi VCL控件的两个属性有点好奇。
每个组件在运行时都有Owner
和Parent
这两个属性。谁能帮助我理解它们之间的区别?它们如何被Windows用于显示控件或窗体?
所有者
是TComponent
中引入的属性,所有者
本身具有TComponent
类型。 所有者
主要用于管理设计组件的生命周期。也就是说,您在表单设计器(或其他设计表面)上放置并完全由框架管理生命周期的组件。 文档中提到:
指示负责流式传输和释放此组件的组件。
创建窗体时,流式传输框架会解析.dfm文件并实例化其中列出的组件。这些组件通常使用指定为该窗体的所有者
创建。
TButton
放置在设计时的 TForm
上。流式框架创建按钮并将其 Owner
设置为该表单。作为 TComponent
的后代,该表单维护着它拥有的所有组件的列表。当该表单被销毁时,它遍历该拥有组件列表并销毁它们。按钮以这种方式被销毁。nil
。在这种情况下,程序员负责销毁该组件。TComponent
的构造函数被声明为虚函数:constructor Create(AOwner: TComponent); virtual;
TComponent
的子类,并希望该派生组件放置在设计表面上,则必须遵守此虚拟构造函数。如果您在TComponent
的子类中定义了构造函数,则必须重写此虚拟构造函数。在VCL术语中,这个概念通过Owned Windows
一个重叠或弹出窗口可以由另一个重叠或弹出窗口拥有。被拥有会对窗口施加几个限制。 - 拥有窗口始终位于其所有者之上。 - 当所有者被销毁时,系统会自动销毁所拥有的窗口。 - 当所有者最小化时,所拥有的窗口将被隐藏。
只有重叠或弹出窗口才能成为所有者窗口;子窗口不能成为所有者窗口。
PopupParent
属性进行公开。该属性是在Delphi 7之后引入的,因此不可用。在Delphi 7中,框架设置窗口所有者,并且没有简单的机制可以覆盖框架的选择。如果您确实需要影响窗口所有权,则必须覆盖CreateParams
并设置Params.WndParent
。不幸的是,在Delphi 7中,VCL处理所有权存在一些问题,有时需要深入研究这些略带血腥的细节。这是完全错误的。对于顶级窗口来说,这是所有者而不是父窗口。WndParent: 父窗口的窗口句柄。这与父控件的Handle属性相同。
Parent
是 TControl
中定义的属性,类型为 TWinControl
。该属性广泛用于公开 Win32 的父子控件概念。Windows 文档 中说:
一个窗口可以有一个父窗口。具有父级的窗口称为子窗口。父窗口提供用于定位子窗口的坐标系统。拥有父窗口会影响窗口外观的某些方面;例如,子窗口被剪切以使其任何部分都不会出现在其父窗口的边框外。没有父级或其父级为桌面窗口的窗口称为顶级窗口。
实际上,VCL 中的 Parent
属性直接映射到 Win32 的父级概念。
Parent
是在 TControl
中定义的。现在,TControl
不是窗口化的,因此在 Win32 意义上,TControl
不是子控件,因为 Win32 窗口的子控件本身就是窗口。因此,具有定义的 Parent
的 TControl
是 VCL 意义上的子控件,称为非窗口化子控件。这些非窗口化控件会作为其父控件的绘图处理程序的一部分进行绘制。这样的控件的典型示例是 TLabel
。TWinControl
的后代)时,它也会销毁其所有子控件。
TWinControl
后代可以使用 ControlCount
和 Controls[]
属性枚举其子控件。这两个属性都可以枚举窗口化和非窗口化子控件。