24 июля 2023

Получение списка дочерних контролов в Delphi 12

    В VCL получить список дочерних контролов у контрола можно с использованием цикла по массиву дочерних контролов TWinControl. Так как некоторые контролы сами могут быть контейнерами для контролов, то метод получения списка контролов на всех уровнях вложенности должен вызываться рекурсивно. В Delphi 12 эту задачу облегчили добавлением TControl Enumerator.
    Сделаем процедуру, которая перебирает все дочерние контролы и добавляет их названия в Memo:
procedure TForm1.GetChildControls(AControl: TWinControl);
var
  ctrl: TControl;
begin
  for var i := 0 to AControl.ControlCount - 1 do
    begin
      ctrl := AControl.Controls[i];
      Memo1.Lines.Add(ctrl.Parent.Name + ' - ' + ctrl.Name);
      if ctrl is TWinControl then
        GetChildControls(ctrl as TWinControl)
    end;
end;
На Delphi 12 с использованием TControl Enumerator код будет значительно проще:
for ctrl in AControl.GetControls(AMyFilter) do
  Memo1.Lines.Add(ctrl.Parent.Name + ' - ' + ctrl.Name);
где параметр AMyFilter – это фильтр контролов, который представляет собой комбинацию элементов типа TControlEnumeratorFilterType:
  • ceftAll – все контролы, включая контролы дочерних контролов (рекурсивный обход);
  • ceftEnabled – контрол должен иметь состояние "Enabled = True";
  • ceftDisabled – контрол должен иметь состояние "Enabled = False";
  • ceftVisible – контрол должен иметь состояние " Visible = True";
  • ceftInvisible – контрол должен иметь состояние " Visible = False";
  • ceftCustom – будет использоваться событие OnEnumerateControl.
Таким образом вопрос с рекурсивным обходом всех дочерних контролов в Delphi 12 решается использованием ceftAll в фильтре GetControls:
procedure TForm1.GetChildControls(AControl: TWinControl);
begin
  for var ctrl in AControl.GetControls([ceftAll]) do
    Memo1.Lines.Add(ctrl.Parent.Name + ' - ' + ctrl.Name);
end;
Очевидно, что такой вариант проще.

Комментариев нет:

Отправить комментарий