Delphi如何访问父窗体

Posted

技术标签:

【中文标题】Delphi如何访问父窗体【英文标题】:How to access to parent form in Delphi 【发布时间】:2016-08-07 20:15:45 【问题描述】:

我正在编写自己的组件,它继承自 TButton。我需要对将放置我的新组件的父表单进行一些操作。

那么,如何从我自己的组件代码中访问父表单?

代码示例(MyComponentCode.pas):

ButtonParent.Canvas.Pen.Color := RGB(255,255,255); // where "ButtonParent" have to be a parent form

帮我解决这个问题。谢谢。

【问题讨论】:

父控件不一定是表单,比如可能是TPanel。明确您需要什么 - 父控件或所有者表单。 @user246408 我需要所有者表格。 那么你需要你的组件的Owner属性;当您将组件拖放到表单上时,IDE 会设置它;我猜你需要了解 Delphi 中 OwnerParent 之间的区别。 @user246408 tnx,它适用于我 @user246408:Owner 保证为TForm如果在设计时将组件放置在TForm 上。如果将其放在TFrame 上,则Owner 将是TFrame。如果组件是在运行时在代码中动态创建的,则Owner 将是调用者传递给组件构造函数的任何内容。组件从不对其Owner(或其Parent)实际上是什么做出任何假设。 【参考方案1】:

要访问您的组件所在的父级 TForm,即使您的组件实际上位于另一个容器控件上(如 TPanelTFrame),请使用 Vcl.Forms 单元中的 GetParentForm() 函数:

uses
  ..., Forms;

var
  Form: TCustomForm;
begin
  Form := GetParentForm(Self);
  //...
end;

【讨论】:

【参考方案2】:

父控件是持有该控件的控件。 如果您将控件放在面板上,则父级将成为面板。

控件的所有者通常是持有它的窗体,但情况并非总是如此。如果您使用框架,则框架将拥有其中的控件。

到达拥有您的控制权的表单的方法是继续向上走,直到找到真正的表单。

您可以拨打VCL.Forms.GetParentForm,如下所示:

function GetParentForm(Control: TControl; TopForm: Boolean = True): TCustomForm;
begin
  while (TopForm or not (Control is TCustomForm)) and (Control.Parent <> nil) do
    Control := Control.Parent;
  if Control is TCustomForm then
    Result := TCustomForm(Control) else
    Result := nil;
end; 

或者,如果您想通过所有者到达那里,您可以这样做:

function GetOwningForm(Control: TComponent): TForm;
var
  LOwner: TComponent;
begin
  LOwner:= Control.Owner;
  while Assigned(LOwner) and not(LOwner is TCustomForm) do begin
    LOwner:= LOwner.Owner;
  end; while
  Result:= LOwner;
end;

了解父母和所有者之间的区别很重要,请参阅:http://delphi.about.com/od/objectpascalide/a/owner_parent.htm

当然,您可以对parent 属性使用相同的技巧。如果您向上爬树足够长的时间(几乎)每个控件1 都会将表单作为其父级。

1) 一些控件没有父控件。

【讨论】:

这是假设Owner 链最终会导致TForm,这是不能保证的。你应该改用GetParentForm()

以上是关于Delphi如何访问父窗体的主要内容,如果未能解决你的问题,请参考以下文章

delphi 子窗体如何调用父窗体的方法

C#中子窗体操作父窗体的变量

Delphi_子窗体继承父窗体后如何显示父窗体上的控件

delphi 如何改变主窗体

js 关闭子窗体时如何刷新父窗体

c#如何把子窗体的值传给父窗体?