c++ builder > TImageが来るからそこ空けるように、の実装 v0.1, v0.2

```txt:動作環境
C++ Builder XE4
```

### やりたいこと

- TImageは普段は隠れている (右側の画面外)
- ある条件でTImageを表示する
   - その場所より下にある複数のコンポーネントを下にずらす

## v0.1 Tag使用

### 実装案

- 特定のTagの値を持つコンポーネントだけずらす

### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <pngimage.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	Image1->Picture->LoadFromFile(L"AD2.png");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_toLeftClick(TObject *Sender)
{
	static const int kTag_move = 79;
	static const int kMargin_down = 10;

	// 1. Image1の高さ分、コンポーネントを下にずらす

	for(int idx=0; idx < this->ComponentCount; idx++) {
		TComponent *aPtr = this->Components[idx];
		if (aPtr->Tag != kTag_move) {
			continue;
		}

		TControl *ctlPtr = (TControl *)aPtr;
		ctlPtr->Top += ( Image1->Height + kMargin_down );
	}

	this->Height += Image1->Height;

	// 2. Image1を左に移動
	Image1->Left = 16;
}
//---------------------------------------------------------------------------
```

## v0.1の結果

### 移動前

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/6c1b0b9e-8d2a-46cb-c06f-8bf4b115fbed.png)

### 移動後

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/74561532-e371-7b3d-9bb3-7300af010299.png)

## 別の案

Tagは他の用途に使う場合もある。

その場合は、TControl *のリストにて、移動対象となるコンポーネントのポインタを格納する。
それらに対してのみ移動処理を実装すればいい。

## v0.2 TControl *のリストで指定

### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <pngimage.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	Image1->Picture->LoadFromFile(L"AD2.png");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_toLeftClick(TObject *Sender)
{
	static const int kMargin_down = 10;

	static TControl *targetList[] = {
		Panel1,
		Button1,
		Label2,
		StringGrid1,
	};
	int targetCount = sizeof(targetList) / sizeof(targetList[0]);


	// 1. Image1の高さ分、コンポーネントを下にずらす

	for(int idx=0; idx < targetCount; idx++) {
		TControl *aPtr = targetList[idx];
		aPtr->Top += ( Image1->Height + kMargin_down );
	}

	this->Height += ( Image1->Height + kMargin_down );

	// 2. Image1を左に移動
	Image1->Left = 16;
}
//---------------------------------------------------------------------------
```

targetList[]の定義は関数内でしているが、他の場所で定義するのが良い。

Tag指定よりこちらがいい点は、コードで意図が分かること。
Tag指定の場合は、フォームデザインでTagを確認しないと、どれが移動対象のコンポーネントか分からない。ソースリーディングしにくくなる。

別の場所でtargetList[]を宣言しようとしたが、あきらめた。
targetList[]に格納するポインタはFormShow処理以降に格納する必要がある。
それを考えると処理が複雑になる。


### 検索用キーワード
(追記 2018/10/18)

- そこのけそこのけ