#delphi
#delphi
Вопрос:
Я хочу иметь возможность использовать одну процедуру для центрирования всех компонентов в форме. Это то, к чему я стремлюсь:
procedure TForm4.centerComponent(x: Tobject);
begin
x.Left := (Form4.ClientWidth - x.Width) div 2;
end;
Я бы передавал только встроенные компоненты (memo, label, edit и т.д.)
У меня такое чувство, что это либо невозможно, либо, вероятно, это не лучшая практика
Ответ №1:
Это просто, но вы должны быть осторожны с терминологией:
-
TObject
— это любой объект Delphi. Это не обязательно должен быть элемент управления. Это даже не обязательно должно быть чем-то, что вы можете поместить в форму. -
TComponent
— это объект, который вы можете поместить в форму. Это может быть визуальный элемент управления (например, кнопка, метка или поле редактирования), или это может быть невизуальный компонент (например,TActionList
). -
TControl
— это визуальный элемент управления, такой как кнопка, метка, окно редактирования или анимированные аналоговые часы.
Вышеуказанные классы упорядочены по наследованию.
Итак, вам нужна процедура, которая действует на TControl
s в целом:
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
является одним конкретным экземпляром класса form. Гораздо лучше написатьSelf.ClientWidth
или простоClientWidth
, чтобы вы ссылались на текущий экземпляр класса form. -
Но даже этого недостаточно, потому что это работает, только если форма является родительской для
x
.x
вполне может иметь другого родителя. Например, уx
может бытьTPanel
родительский элемент (родительским элементомTPanel
является форма).