RAD Studio 10.2 Tokyo Update 2 + Windows 10 Pro (v1709)
Windows 10 Pro (v1709)
Windows 8.1 Pro
Windows 7 Pro
関連
処理概要
フォームを並べるソフトを試していて、C++ Builder 10.2 Tokyoでビルドした場合にフォーム間に「空き」ができる。
さらに調べていると、10.2 Tokyoの問題ではなく、Windows 10での実行時に空きができるらしいことが見られた。
再現用のコードとして以下を試してみる。
//---------------------------------------------------------------------------
#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
//---------------------------------------------------------------------------
#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];
}
}
//---------------------------------------------------------------------------
本来は右側の子フォームが左の子フォームにくっつくはずだが、そうはならない。
発生状況は以下の通り
- Windows 10: 空きが生じる
- Windows 8.1: 空きは生じない
- Windows 7: 空きは生じない
Windows 10で「テキスト、アプリ、その他の項目のサイズを変更する」は「100%」でも「175%」でも同じように空きが生じる。
フォームのプロパティ「Scaled」をfalseにしても同じ。
座標の確認
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());
}
マウス座標を表示するようにしてみた。
確認したところ、子フォームが縮小表示されているようだ。
(追記: この点は間違いだったようです)
関連
Vista以降の変更について記載されている。こちらでの確認ではVista以降というよりはWindows 10自体の違いの感じはする。
ClientWidthを使うという提案がされている。
実際にClientWidthに変更したら、下記のように子フォームが連結するようになった。
Windows8.1まで座標関係が問題なかったソフトもWindows 10で使用するときに変更することになるかもしれない(WidthからClientWidthへの変更)。
上記の理由
C++ Builder 10.2 Tokyo > WidthとClientWidthの違い on (Win7, Win8.1, Win10) > 同じように違う | フォーム外側の枠: Win10にはない
に見られるように、Windows 10においてウィンドウ枠(左、右、下)が表示されないことによるようだ。
この問題はXE4でビルドしたソフトでも生じるだろう。