子コントロールを列挙するには?

とあるコントロールの子コントロールは Children プロパティで取得できます。例えば Form1 上にあるコントロールの名前を Memo1 に表示するには以下のようになります。

[XE3 以降]

procedure TForm1.Button1Click(Sender: TObject);
var
  FmxObj: TFMXObject;
  i: Integer;
begin
  for i:=0 to Form1.ChildrenCount-1 do
    begin
      FmxObj := Form1.Children.Items[i];
      if FmxObj.Name <> '' then
      Memo1.Lines.Add(FmxObj.Name);
    end;
end;

[XE2]

procedure TForm1.Button1Click(Sender: TObject);
var
  FmxObj: TFMXObject;
  i: Integer;
begin
  for i:=0 to Form1.ChildrenCount-1 do
    begin
      FmxObj := Form1.Children[i];
      if FmxObj.Name <> '' then
      Memo1.Lines.Add(FmxObj.Name);
    end;
end;

名無しのコントロールは設計時に作成されたものではないので列挙していません。

…ですが、これはあくまで Form1 の直下にある子コントロールしか列挙できません。子コントロールがさらに子コントロールを持っており、それらすべてのコントロールを列挙するためには再帰を使って取得する必要があります。

[XE3 以降]

procedure TForm1.Button1Click(Sender: TObject);
  { EnumControl BEGIN}
  procedure EnumControl(FmxObj: TFmxObject; Recursive: Boolean);
  var
    i: Integer;
  begin
    if FmxObj = nil then
      Exit;
    Memo1.Lines.Add(FmxObj.Name);
    if Recursive then
      for i:=0 to FmxObj.ChildrenCount-1 do
        if FmxObj.Children.Items[i].Name <> '' then
          EnumControl(FmxObj.Children.Items[i], Recursive);
  end;
  { EnumControl END}
begin
  EnumControl(Form1 , True);
end;

[XE2]

procedure TForm1.Button1Click(Sender: TObject);
  { EnumControl BEGIN}
  procedure EnumControl(FmxObj: TFmxObject; Recursive: Boolean);
  var
    i: Integer;
  begin
    if FmxObj = nil then
      Exit;
    Memo1.Lines.Add(FmxObj.Name);
    if Recursive then
      for i:=0 to FmxObj.ChildrenCount-1 do
        if FmxObj.Children[i].Name <> '' then
          EnumControl(FmxObj.Children[i], Recursive);
  end;
  { EnumControl END}
begin
  EnumControl(Form1 , True);
end;

副作用として EnumControl() に指定したコントロールも列挙されてしまいますが、大した問題ではないでしょう。


 BACK