如何在 Delphi 中将组件作为过程的参数传递?

How to pass a component as a parameter of a procedure in Delphi?

我希望能够使用一个过程将所有组件集中在一个窗体上。这就是我想要的东西:

procedure TForm4.centerComponent(x: Tobject);
begin
x.Left := (Form4.ClientWidth - x.Width) div 2;
end;

我只会传递内置组件(备忘录、标签、编辑等...) 我觉得这要么不可能,要么可能不是最佳实践

这很简单,但您必须注意术语:

  • A TObject 是任何 Delphi object。它不需要是一个控件。它甚至不需要是您可以放在表格上的东西。

  • 一个 TComponent 是一个 object 你可以放在一个表格上。它可能是一个可视控件(如按钮、标签或编辑框),也可能是 non-visual 组件(如 TActionList)。

  • TControl 是一个视觉控件,如按钮、标签、编辑框或动画模拟时钟。

以上class按继承排序。

因此,您需要一个通常作用于 TControl 的过程:

procedure Centre(AControl: TControl);
var
  Parent: TWinControl;
begin
  Parent := AControl.Parent;
  if Parent = nil then
    Exit;
  AControl.SetBounds(
    (Parent.ClientWidth - AControl.Width) div 2,
    (Parent.ClientHeight - AControl.Height) div 2,
    AControl.Width,
    AControl.Height
  );
end;

每个 TControl 都有 TopLeftWidthHeight 属性,以及 SetBounds 方法,它我们在上面使用。

请注意,我将控件置于 parent window 的中心。 (控件的 TopLeft 值总是相对于它的 parent。)

现在Delphi中有两种控件:

  • 实际 Win32 控件 windows(带 HWND)。
  • 不是实际 Win32 的控件windows。

只有前一种控件可以有child控件。这些控件源自 TWinControl。这就是我将 Parent 声明为 TWinControl 的原因。这也是TControl.Parent属性.

的类型

关于您的代码的一些说明

x.Left := (Form4.ClientWidth - x.Width) div 2;

这里有两个问题(除了 x: TObject 没有任何 WidthLeft 属性):

  • Form4 形式 class 的一个特定 实例。写 Self.ClientWidth 或简单地写 ClientWidth 会好得多,所以你引用 current 形式的实例 class.

  • 但即使这样还不够好,因为只有当表单是 x 的 parent 时才有效。 x 可能会有不同的 parent。例如,x 可能有一个 TPanel 作为它的 parent(TPanel 的 parent 是形式)。