Многие начинающие Delphi программисты при динамическом создании компонент путаются со свойствами Owner и Parent. Попробую внести некоторую ясность.
Для начала определим, за что же отвечают эти свойства.
- Parent (TWinControl) - родитель. Задаётся прямым указанием после создания компонента. Отвечает за отрисовку компонента.
- Owner (TComponent) - владелец. Задаётся при создании компонента, как параметр конструктора Create. Отвечает за удаление компонента. Т.е. при уничтожении компонента, он вызывает уничтожение всех, у которых он указан в качестве владельца.
Среда Delphi, когда программист перетаскивает компоненты с панели компонентов на форму автоматически присваивает создаваемому компоненту владельцем Форму, а родителем тот компонент, на который осуществлено перетаскивание.
Для поиска компонент существуют методы:
- TComponent.FindComponent(const AName: string): TComponent ищет среди компонент, у которых текущий указан в качестве владельца.
- TWinControl.FindChildControl(const AName: string): TControl - ищет среди дочерних контролов. Тут необходимо уточнить, что если на панели Panel1, лежит другая панель Panel2, а не ней уже поле ввода EditName, то при вызове Panel1.FindChildControl(EditName) функция вернёт nil. Т.к. для Panel1 дочерним является только Panel2.
Часто удобно именно «динамическое» обращение к компонентам по их имени. Например, когда необходимо установить Enabled у всех TEdit на форме, или только на одной какой-то панели. Или же, только у компонент по списку имён, например, аналогичных названиям полей в запросе из БД. Или, если сохранены имена компонент по умолчания, то по номерам (диапазонам номеров)
Для примера приведу код процедуры, в которой осуществляется выравнивание пар контролов (метка TLabel и поле ввода TEdit) в зависимости от видимости полей ввода. Т.е. на форме, на Panel1 лежат все необходимые поля ввода, но при создании формы в зависимости от параметров часть из них скрывается. Возникла необходимость выровнить остальные по высоте.
procedure TForm1.SetParamPosition; var nTopEd, nTopLb: integer; i: integer; st: string; lb, ed: TControl; begin // устанавливаем видимые компонеты по высоте. nTopEd := 22; nTopLb := 25; for i := 0 to 5 do begin case i of 0: st := 'Group'; 1: st := 'SubGroup'; 2: st := 'Code'; 3: st := 'Name'; 4: st := 'Spec'; 5: st := 'Status'; end; lb := TControl(FindComponent('lb' + st)); ed := Panel1.FindChildControl('ed' + st); if Assigned(lb) and Assigned(ed) then begin lb.Visible := ed.Visible; lb.Top := nTopLb; ed.Top := nTopEd; if ed.Visible then begin nTopEd := nTopEd + ed.Height + 6; nTopLb := nTopLb + ed.Height + 6; end; end; end; end;