2018-11-09 Windows 10 > bug > geometry > ウィンドウのタイトルバー非表示、表示にてウィンドウの位置がずれる > Windows 10にて「テキスト、アプリ、その他の項目のサイズ」が100%でない時に発生する  | 対処: Hide(), Show()する

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

### 関連

- [C++ Builder > TForm > タイトルバーのないウィンドウ(サイズ変更可能)の実装 > ボタン押下による表示、非表示](https://qiita.com/7of9/items/76ff36bb604ee6868f85)

### 概要

上記で実装したソフトにて下記の操作をするとウィンドウの位置がずれる。

- ウィンドウのタイトルバーを非表示にする
- ウィンドウのタイトルバーを表示にする
    - ウィンドウの位置が下にずれる

### 発生条件

- 4K UHDモニタ
    - 追記: FullHDモニタでも発生
- ディスプレイ設定
    - 拡大縮小とレイアウト
        - テキスト、アプリ、その他の項目のサイズを変更する
            - 150%(推奨)

上記のように150%設定時、ずれが起きる。

ただし、ずれた状態で他のウィンドウにフォーカスが移ると（クリックすると）、元の位置に戻る。

- Windows 10 + テキスト150%
    - 位置ずれが発生する
- Windows 7 + テキスト150%
    - 位置ずれは発生しない

<!--
### 解決方法

- フォームのScaledプロパティをfalseにする
    - 参考: [高DPIの問題の分析、VCL FOR C++ BULIDER OR DELPHI](http://hudson.doorblog.jp/archives/41943232.html)

情報感謝です。
-->


### 試したこと

```
動作環境: Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
```

- [ディスプレイのカスタマイズでサイズの倍率を変更すると、スクリーンサイズが正しく取得できない](https://ja.stackoverflow.com/questions/19544/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%81%A7%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%AE%E5%80%8D%E7%8E%87%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B%E3%81%A8-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%8C%E6%AD%A3%E3%81%97%E3%81%8F%E5%8F%96%E5%BE%97%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)

上記の情報をもとにアプリケーションマニフェストを作成し高DPI対応にしてみた。

不具合は解消しなかった。

### 対処 > Hide(), Show()する

ウィンドウを一旦隠して、表示しなおすと対処できることが分かった。

下記のような処理を加える。

```cpp
	// Windows 10 「テキスト、アプリ、その他の項目のサイズを変更する」を150などにした時に位置がずれる問題の対処
	this->Hide();
	Application->ProcessMessages();
	Sleep(50); // msec. 50: 任意の時間
	this->Show();
```

ソフト起動直後
<img width="570" alt="2018-11-11_10h34_29.png" src="https://qiita-image-store.s3.amazonaws.com/0/32870/e044e987-fc17-325a-f353-834926b86074.png">

B_hide, B_show1の後 > 下にずれている（異常）
<img width="549" alt="2018-11-11_10h35_25.png" src="https://qiita-image-store.s3.amazonaws.com/0/32870/c483d48e-76a5-3558-ad58-c05afe5e3761.png">

B_hide, B_show2の後 > ずれていない (正常)
<img width="561" alt="2018-11-11_10h35_45.png" src="https://qiita-image-store.s3.amazonaws.com/0/32870/9fb61d6b-944e-3a26-902e-6175e8d7340e.png">

上記、実行例の実装。

```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_hide;
	TButton *B_show2;
	TButton *B_show1;
	void __fastcall B_hideClick(TObject *Sender);
	void __fastcall B_show2Click(TObject *Sender);
	void __fastcall B_show1Click(TObject *Sender);
private:	// ユーザー宣言
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)
{
	this->Position = poScreenCenter; // 画面中央に表示
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_hideClick(TObject *Sender)
{
	DWORD astyle;

	astyle = GetWindowLong(this->Handle, GWL_STYLE);
	SetWindowLong(this->Handle, GWL_STYLE, astyle & ~WS_CAPTION);

	// SetWindowLongの変更適用
	SetWindowPos(this->Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_show1Click(TObject *Sender)
{
	// Windows 10にて位置ずれが起きる実装

	DWORD astyle = GetWindowLong(this->Handle, GWL_STYLE);
	SetWindowLong(this->Handle, GWL_STYLE, astyle | WS_CAPTION);

	// SetWindowLongの変更適用
	SetWindowPos(this->Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}

void __fastcall TForm1::B_show2Click(TObject *Sender)
{
	// Windows 10にて位置ずれが起きる実装

	DWORD astyle = GetWindowLong(this->Handle, GWL_STYLE);
	SetWindowLong(this->Handle, GWL_STYLE, astyle | WS_CAPTION);

	// SetWindowLongの変更適用
	SetWindowPos(this->Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);

	// Windows 10 「テキスト、アプリ、その他の項目のサイズを変更する」を150などにした時に位置がずれる問題の対処
	this->Hide();
	Application->ProcessMessages();
	Sleep(50); // msec. 50: 任意の時間
	this->Show();
}
//---------------------------------------------------------------------------
```