C++ Builder XE4, 10.2 Tokyo > フォームの座標位置 > WidthでなくClientWidthを使う (Win10対応)

```txt:ビルド環境
RAD Studio 10.2 Tokyo Update 2 + Windows 10 Pro (v1709)
```

```txt:実行環境
Windows 10 Pro (v1709)
Windows 8.1 Pro
Windows 7 Pro
```

### 関連

- [C++ Builder 10.2 Tokyo > Forms > Bug > 8個の子フォームを親フォームの下に4行 x 2列で配置する > 空白があいてしまう > 10.2 Tokyoの問題ではなさそう](https://qiita.com/7of9/items/426360c66715d276bc0d)

### 処理概要

フォームを並べるソフトを試していて、C++ Builder 10.2 Tokyoでビルドした場合にフォーム間に「空き」ができる。
さらに調べていると、10.2 Tokyoの問題ではなく、Windows 10での実行時に空きができるらしいことが見られた。

再現用のコードとして以下を試してみる。

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *B_makeDouble;
	void __fastcall B_makeDoubleClick(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
    __fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

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

#include <vcl.h>
#pragma hdrstop

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

TForm2 *s_forms[2] = {NULL, NULL};

void __fastcall TForm1::B_makeDoubleClick(TObject *Sender)
{
	// 1. フォームの作成
	if (s_forms[0] == NULL) {
		s_forms[0] = new TForm2(this);
	}
	if (s_forms[1] == NULL) {
		s_forms[1] = new TForm2(this);
	}
	s_forms[0]->Show();
	s_forms[1]->Show();

	// 2. 位置調整
	s_forms[1]->Top = s_forms[0]->Top;

	s_forms[0]->Left = this->Left + B_makeDouble->Left + B_makeDouble->Width;
	s_forms[1]->Left = s_forms[0]->Left + s_forms[0]->Width;

}

__fastcall TForm1::~TForm1()
{
	if (s_forms[0] != NULL) {
		delete s_forms[0];
	}
	if (s_forms[1] != NULL) {
		delete s_forms[1];
	}
}
//---------------------------------------------------------------------------

```

![2018-01-09_11h57_06.png](https://qiita-image-store.s3.amazonaws.com/0/32870/17e94ef1-8543-1fa7-e628-4700f65d1407.png)

本来は右側の子フォームが左の子フォームにくっつくはずだが、そうはならない。

発生状況は以下の通り

- Windows 10: 空きが生じる
- Windows 8.1: 空きは生じない
- Windows 7: 空きは生じない

Windows 10で「テキスト、アプリ、その他の項目のサイズを変更する」は「100%」でも「175%」でも同じように空きが生じる。
フォームのプロパティ「Scaled」をfalseにしても同じ。

### 座標の確認

```Unit1.cpp
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
	TPoint pt;

	pt = Mouse->CursorPos;

	String msg = IntToStr((int)pt.X) + L"," + IntToStr((int)pt.Y);
	OutputDebugString(msg.c_str());
}
```

マウス座標を表示するようにしてみた。
~~確認したところ、子フォームが縮小表示されているようだ。~~
(追記: この点は間違いだったようです)

### 関連

- [Windows10でフォームのサイズ、位置が思い通りにならない](http://madia.world.coocan.jp/cgi-bin/DelphiBBS/wwwlng.cgi?print+201703/17030007.txt)

Vista以降の変更について記載されている。こちらでの確認ではVista以降というよりはWindows 10自体の違いの感じはする。
ClientWidthを使うという提案がされている。

実際にClientWidthに変更したら、下記のように子フォームが連結するようになった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7092b922-79ff-9120-368f-f3793b10fefc.png)

**Windows8.1まで座標関係が問題なかったソフトもWindows 10で使用するときに変更することになるかもしれない(WidthからClientWidthへの変更）。**

### 上記の理由

[C++ Builder 10.2 Tokyo > WidthとClientWidthの違い on (Win7, Win8.1, Win10) > 同じように違う | フォーム外側の枠: Win10にはない](https://qiita.com/7of9/items/810a174e9dd7d66367d3)
に見られるように、Windows 10においてウィンドウ枠（左、右、下）が表示されないことによるようだ。

この問題はXE4でビルドしたソフトでも生じるだろう。