代码之家  ›  专栏  ›  技术社区  ›  A B

控件的所有者和父级之间的区别是什么?

  •  11
  • A B  · 技术社区  · 9 年前

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

    每个组件有2个属性 Owner Parent 在运行时。有人能帮我理解两者的区别吗?窗口如何使用它们来显示控件或窗体?

    1 回复  |  直到 9 年前
        1
  •  27
  •   David Heffernan    8 年前

    物主

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

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

    创建表单时,流框架解析.dfm文件并实例化其中列出的组件。这些组件通常使用 物主 指定为表单。

    组件生命的另一端是破坏。当一个组件被销毁时,它也会销毁它所拥有的所有组件。为了一个具体的例子,请考虑 TButton 位于 TForm ,在设计时放置在那里。流式框架创建设置其 物主 作为形式的后代 T组件 维护其拥有的所有组件的列表。当表单被销毁时,它会遍历拥有的组件列表并销毁它们。按钮以这种方式被破坏。

    这有很多细微差别:

    • 组件不需要由窗体拥有。例如,在运行时创建的组件由传递给构造函数的任何组件拥有。
    • 组件无需拥有所有者,您可以通过 nil 到构造函数。在这种情况下,程序员仍然负责销毁组件。
    • 所有权可以在组件的生命周期内更改。

    因为流框架实例化组件 T组件 声明为虚拟:

    constructor Create(AOwner: TComponent); virtual;
    

    如果您从 T组件 如果您希望将派生组件放置在设计图面上,则必须尊重此虚拟构造函数。如果在 T组件 则它必须重写此虚拟构造函数。

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

    拥有的Windows

    重叠窗口或弹出窗口可以由另一个重叠窗口或 弹出窗口。拥有对一个窗口有几个限制。 -所属窗口始终在其所有者的z顺序上方。 -当所有者被销毁时,系统会自动销毁所拥有的窗口。 -拥有的窗口在其所有者最小化时隐藏。

    只有重叠或弹出窗口可以是所有者窗口;一个孩子 窗口不能是所有者窗口。

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

    为了显示混淆是多么容易,VCL documentation 说:

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

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

    父母亲

    Parent 是中定义的属性 TControl 并且具有类型 TWinControl 。此属性广泛用于公开父控件和子控件的Win32概念。这个 Windows documentation 说:

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

    基本上,VCL 父母亲 属性直接映射到Win32父概念。

    然而,请注意 父母亲 在中定义 T控制 现在 T控制 没有窗口,因此 T控制 不是Win32意义上的子控件,因为Win32窗口的子控件本身就是窗口。所以,a T控制 具有定义的 父母亲 是VCL意义上的子控件,称为非窗口子控件。这些非窗口控件将自己绘制为其父级绘制处理程序的一部分。此类控件的典型示例是 TLabel .

    注意,当一个窗口控件,即 TWin控制 后代,被摧毁,它也摧毁了它的所有孩子。

    A. TWin控制 子代可以使用 ControlCount Controls[] 属性。这些枚举了有窗和无窗的子对象。