我希望能够使用一个过程将所有组件集中在一个表单上
procedure TForm4.centerComponent(x: Tobject);
begin
x.Left := (Form4.ClientWidth - x.Width) div 2;
end;
我只会传递内置组件(备忘录、标签、编辑等(我觉得这要么是不可能的,要么可能不是的最佳实践
这很容易,但您必须小心术语:
-
TObject
是任何Delphi对象。它不一定是一种控制。它甚至不需要是你可以放在表格上的东西。 -
TComponent
是一个可以放置在窗体上的对象。它可能是一个可视控件(如按钮、标签或编辑框(,也可能是一种非可视组件(如TActionList
(。 -
TControl
是一个视觉控件,如按钮、标签、编辑框或动画模拟时钟。
上述类是按继承顺序排列的。
所以,你想要一个作用于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
都有Top
、Left
、Width
和Height
的性质,以及我们上面使用的SetBounds
方法。
请注意,我将控件集中在其父窗口中。(控件的Top
和Left
值始终相对于其父控件。(
现在,Delphi中有两种控件:
- 控件是实际的Win32窗口(带有HWND(
- 不是实际Win32窗口的控件
只有前一种控件才能有子控件。这些控件源自TWinControl
。这就是我将Parent
声明为TWinControl
的原因。这也是TControl.Parent
属性的类型。
关于代码的一些注释
x.Left := (Form4.ClientWidth - x.Width) div 2;
这里有两个问题(除了x: TObject
没有任何Width
或Left
属性之外(:
Form4
是表单类的一个特定实例。编写Self.ClientWidth
或简单地编写ClientWidth
要好得多,因此您可以引用表单类的当前实例。但即使这样也不够好,因为只有当表单是
x
的父级时,这才有效。x
很可能有一个不同的父代。例如,x
可能有一个TPanel
作为它的父级(TPanel
的父级是表单(。