Delphi でコントロール配列 [小ネタ]

# はじめに
Delphi には (Classic) Visual Basic のような**コントロール配列**はありませんが、コントロールの配列にコントロールを割り当てる事で似たような事ができました。

 - [ＶＢのコントロール配列はDelphiではどうやって実現すればいいのでしょうか？ (Delphi Users' Forum FDELPHI ミラー)](http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/faq/00115.htm)

今回は動的配列でそれをやってみます。

# コード
TButton の**動的配列**を作るコードとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/7ef29a22-5b9e-927d-53c7-51df8ab22f40.png)
テストは VCL アプリケーションで行いますが、FireMonkey でも考え方は同じです。

## Delphi 2005 以降

Delphi 2005 以降だと**配列コンストラクタ**が使えるので、次のような書き方ができます。

```pascal
procedure TForm1.FormShow(Sender: TObject);
type
  TBtnDynArray = array of TButton;
var
  BtnArr: TBtnDynArray;
  i: Integer;
begin
  OnShow := nil;

  BtnArr := TBtnDynArray.Create(
              TButton.Create(Self),
              TButton.Create(Self),
              TButton.Create(Self)
            );

  for i:=Low(BtnArr) to High(BtnArr) do
    with BtnArr[i] do
      begin
        Parent  := Self;
        Width   := 96;
        Height  := 24;
        Left    := 12;
        Top     := i * 32 + 12;
        Caption := Format('Button_%.2d', [Succ(i)]);
      end;
end;

```

**See also:**

 - [動的配列 (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E6%A7%8B%E9%80%A0%E5%8C%96%E5%9E%8B%EF%BC%88Delphi%EF%BC%89#.E5.8B.95.E7.9A.84.E9.85.8D.E5.88.97)

## Delphi XE7 以降
Delphi XE7 以降だと**配列定数式**が使えるので、次のような書き方ができます。

```pascal
procedure TForm1.FormShow(Sender: TObject);
var
  BtnArr: array of TButton;
  i: Integer;
begin
  OnShow := nil;

  BtnArr := [
              TButton.Create(Self),
              TButton.Create(Self),
              TButton.Create(Self)
            ];

  for i:=Low(BtnArr) to High(BtnArr) do
    with BtnArr[i] do
      begin
        Parent  := Self;
        Width   := 96;
        Height  := 24;
        Left    := 12;
        Top     := i * 32 + 12;
        Caption := Format('Button_%.2d', [Succ(i)]);
      end;
end;
```

後でコントロールを足す事もできます。

```pascal
  BtnArr := BtnArr + [TButton.Create(Self)];

  with BtnArr[High(BtnArr)] do
    begin
      Parent  := Self;
      Width   := 96;
      Height  := 24;
      Left    := 12;
      Top     := High(BtnArr) * 32 + 12;
      Caption := Format('Button_%.2d', [Length(BtnArr)]);
    end;
```

**See also:**

 - [動的配列に対する文字列風の操作をサポート - Delphi XE7 の新機能 (DocWiki)](http://docwiki.embarcadero.com/RADStudio/XE7/ja/Delphi_XE7_%E3%81%8A%E3%82%88%E3%81%B3_C%2B%2BBuilder_XE7_%E3%81%AE%E6%96%B0%E6%A9%9F%E8%83%BD#.E5.8B.95.E7.9A.84.E9.85.8D.E5.88.97.E3.81.AB.E5.AF.BE.E3.81.99.E3.82.8B.E6.96.87.E5.AD.97.E5.88.97.E9.A2.A8.E3.81.AE.E6.93.8D.E4.BD.9C.E3.82.92.E3.82.B5.E3.83.9D.E3.83.BC.E3.83.88)

## Delphi 10.3 Rio 以降
Delphi 10.3 Rio 以降だと**インライン変数宣言**と**型推論**ができるので、次のような書き方ができます。

```pascal
procedure TForm1.FormShow(Sender: TObject);
begin
  OnShow := nil;

  var BtnArr := [
                  TButton.Create(Self),
                  TButton.Create(Self),
                  TButton.Create(Self)
                ];

  for var i:=Low(BtnArr) to High(BtnArr) do
    with BtnArr[i] do
      begin
        Parent  := Self;
        Width   := 96;
        Height  := 24;
        Left    := 12;
        Top     := i * 32 + 12;
        Caption := Format('Button_%.2d', [Succ(i)]);
      end;
end;
```

**See also:**

 - [インライン変数宣言, 型推論 - Delphi 10.3 Rio の新機能 (DocWiki)](http://docwiki.embarcadero.com/RADStudio/Rio/ja/%E6%96%B0%E6%A9%9F%E8%83%BD#.E3.82.A4.E3.83.B3.E3.83.A9.E3.82.A4.E3.83.B3.E5.A4.89.E6.95.B0.E5.AE.A3.E8.A8.80)

# おわりに
新しい機能を使うと便利な書き方ができるものですね。

**See also:**

 - [Dynamic Arrays in Delphi XE7 (Marco Tech Blog)](https://blog.marcocantu.com/blog/2014_september_dynamic_arrays_delphixe7.html)
 - [<6> 構造化型の概要と配列型 (標準 Pascal 範囲内での Delphi 入門) (Qiita)](https://qiita.com/ht_deko/items/eedda6d38b6d0887d4ac)