C++ Builder XE4 > Form > フォーム上のコンポーネントの配置を比率で行う

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

## コンポーネントの自動配置

コンポーネントの自動配置としてAnchorsプロパティがある。
AnchorsプロパティのakLeft, akTop, akRight, akBottomを全てTrueにすると、フォーム拡大時にフォームサイズに合わせてコンポーネントサイズが変更される。

しかしながら、それは「絶対値」での変更であり、複数のコンポーネントがある場合に希望の動作にならない。

初期状態
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/8c837e4b-97da-83d2-b5ed-ebededa16da5.png)

拡大時
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/237870b9-ac1f-7dea-2b5d-05c72838abb3.png)

## 配置を比率で行う

配置を「絶対値」でなく「比率」で行うようにしてみる。

### code

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TStringGrid *StringGrid1;
	TStringGrid *StringGrid2;
	TStringGrid *StringGrid3;
	void __fastcall FormResize(TObject *Sender);
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
	void __fastcall FormShow(TObject *Sender);
private:	// ユーザー宣言
	void __fastcall registerComponents(TForm *formPtr, TControl *ctlPtr);
	void __fastcall releaseComponents(void);
	void __fastcall resizeWithRatio(void);
	TList *m_ctlList;  // 位置情報の構造体リスト
	struct POSI_RATIO { // 位置情報の構造体
		TControl *ctlPtr;
		double left;
		double top;
		double width;
		double height;
	};
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	m_ctlList = new TList();
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
	releaseComponents();

	m_ctlList->Clear();
	delete m_ctlList;
}

//---------------------------------------------------------------------------

void __fastcall TForm1::registerComponents(TForm *formPtr, TControl *ctlPtr)
{
	POSI_RATIO *posRat;

	posRat = new POSI_RATIO;
	posRat->ctlPtr = ctlPtr;
	posRat->left = (double)ctlPtr->Left / formPtr->Width;
	posRat->top = (double)ctlPtr->Top / formPtr->Height;
	posRat->width = (double)ctlPtr->Width / formPtr->Width;
	posRat->height = (double)ctlPtr->Height / formPtr->Height;

	m_ctlList->Add(posRat);
}

void __fastcall TForm1::releaseComponents(void)
{
	POSI_RATIO *posRat;

	if (m_ctlList == NULL) {
		return;
	}

	for(int idx=0; idx < m_ctlList->Count; idx++) {
		posRat = (POSI_RATIO *)m_ctlList->Items[idx];
		delete posRat;
	}
}

void __fastcall TForm1::resizeWithRatio(void)
{
	POSI_RATIO *posRat;

	for(int idx=0; idx < m_ctlList->Count; idx++) {
		posRat = (POSI_RATIO *)m_ctlList->Items[idx];
		posRat->ctlPtr->Left = posRat->left * this->Width;
		posRat->ctlPtr->Top = posRat->top * this->Height;
		posRat->ctlPtr->Width = posRat->width * this->Width;
		posRat->ctlPtr->Height = posRat->height * this->Height;
	}
}

void __fastcall TForm1::FormResize(TObject *Sender)
{
	resizeWithRatio();
}

void __fastcall TForm1::FormShow(TObject *Sender)
{
	registerComponents(this, this->StringGrid1);
	registerComponents(this, this->StringGrid2);
	registerComponents(this, this->StringGrid3);
}
//---------------------------------------------------------------------------
```

### 実行例

初期状態
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/eb6bd347-dc69-a976-e255-4308978bac1b.png)

拡大時
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/e9354278-c2de-2ba1-2720-df90f9b47318.png)

コンポーネントが重なることはなくなった。

比率でのサイズ変更のため、拡大時にマージン(絶対値)自体も大きくなる。