C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」変更状態でフォームのHeight, Widthを設定する実装

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

### 関連

[C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」 > 中(M)や大(L)の場合にウィンドウサイズが変化する](https://qiita.com/7of9/items/a133abbacb648c31d6a5)

### 実装

FormのプロパティScaledをfalseにする方法などもあるかもしれない。

以下ではScaledをtrueのまま対応する一つの方法を取る。

### code

SetSizeRelativeToPixelsPerInch()を追加した。

```UtilScreen.h
//---------------------------------------------------------------------------

#ifndef UtilScreenH
#define UtilScreenH

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

/*
フォームのサイズ変更関連を処理する
*/

class CUtilScreen {
private:
	//

public:
	static void __fastcall CUtilScreen::AutoSizeSetting(TForm *formsPtr[], int num);
	static void __fastcall CUtilScreen::SetSizeRelativeToPixelsPerInch(TForm *formPtr, int height, int width);
};

#endif
```

```UtilScreen.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <memory>
#include "UtilScreen.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

#define DEBUG_DO_PRINT // デバッグ出力

/*
v0.8 2017/11/21
	- SetSizeRelativeToPixelsPerInch()追加
v0.7 2017/10/09
	- fix bug: 引数のNULLチェック漏れ
		+ fix AutoSizeSetting()
v0.6 2015/11/12
	- DEBUG_PRINT マクロを DEBUG_DO_PRINT に変更した。DEBUG_PRINTは関数マクロとして使われる例があるため
v0.5 2015/11/03
	- AutoSizeSetting()を実装した。
*/

static void debug_outputDebugString(String prefix, String msg)
{
	// あとでまとめてデバッグ出力をコメントアウトするため、関数にしている。

#ifdef DEBUG_DO_PRINT
	String work = L"UtilScreen >" + prefix + L": " + msg;
	OutputDebugString(work.c_str()); // @ debug_outputDebugString
#endif
}

/* static*/void __fastcall CUtilScreen::AutoSizeSetting(TForm *formsPtr[], int num)
{
	if (formsPtr == NULL) {
		String msg = L"Line36 > Error [formsPtr] is NULL";
		debug_outputDebugString(/*prefix=*/L"CUtilScreen", msg);
		return;// error
	}

	// 基準となるノートPCの解像度
	int noteW = 1367;
	int noteH = 768;

	int myW = Screen->Monitors[0]->Width;
	int myH = Screen->Monitors[0]->Height;

	// 小さい場合も対応することにしたので、以下はコメントにした
//	if (myW <= noteW && myH <= noteH) {
//		return;
//	}

	float ratioH = (float)myH / (float)noteH;
	float ratioW = (float)myW / (float)noteW;

	int setRatio;
	if (ratioH < ratioW) {
		setRatio = ratioH * 100; // 少数第二位まで扱う
	} else {
		setRatio = ratioW * 100;
	}

	for(int idx=0; idx < num; idx++) {
		formsPtr[idx]->ScaleBy(setRatio, 100);
	}

}

/*static*/void __fastcall CUtilScreen::SetSizeRelativeToPixelsPerInch(TForm *formPtr, int height, int width)
{
	/*
	「テキストやその他の項目の大きさの変更」にて「小」から変更された状態でフォームサイズ変更処理を行うと
	フォームが期待通りのサイズにならない。下記にて比率を考慮したサイズ設定を行う。
	*/

	static const int kDefault_PixelsPerInch = 96;

	if (formPtr == NULL) {
		return; // error
	}

	int ppi = formPtr->PixelsPerInch;
	formPtr->Height = height * ppi / kDefault_PixelsPerInch;
	formPtr->Width = width * ppi / kDefault_PixelsPerInch;
}
```

### 使用コード例

FormShow()にて使う。

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "UtilScreen.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int dpi  = this->PixelsPerInch;
	ShowMessage(IntToStr(dpi));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	CUtilScreen::SetSizeRelativeToPixelsPerInch(this, /*height=*/338, /*width=*/651);
}
//---------------------------------------------------------------------------
```


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

- 拡大
-