我希望能够使用一个过程来将表单上的所有组件居中。这就是我所追求的类型:
procedure TForm4.centerComponent(x: Tobject);
begin
x.Left := (Form4.ClientWidth - x.Width) div 2;
end;
我只会传递内置组件(memo、label、edit等)。 我有一种感觉,这要么不可能,要么即使可能也不是最佳实践。
我希望能够使用一个过程来将表单上的所有组件居中。这就是我所追求的类型:
procedure TForm4.centerComponent(x: Tobject);
begin
x.Left := (Form4.ClientWidth - x.Width) div 2;
end;
我只会传递内置组件(memo、label、edit等)。 我有一种感觉,这要么不可能,要么即使可能也不是最佳实践。
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中有两种控件:
只有前一种类型的控件可以拥有子控件。这些控件派生自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
的父容器是该表单)。