動作環境
C++ Builder XE4
関連
概要
上記で実装したソフトにて下記の操作をするとウィンドウの位置がずれる。
- ウィンドウのタイトルバーを非表示にする
- ウィンドウのタイトルバーを表示にする
- ウィンドウの位置が下にずれる
発生条件
- 4K UHDモニタ
- 追記: FullHDモニタでも発生
- ディスプレイ設定
- 拡大縮小とレイアウト
- テキスト、アプリ、その他の項目のサイズを変更する
- 150%(推奨)
- テキスト、アプリ、その他の項目のサイズを変更する
- 拡大縮小とレイアウト
上記のように150%設定時、ずれが起きる。
ただし、ずれた状態で他のウィンドウにフォーカスが移ると(クリックすると)、元の位置に戻る。
- Windows 10 + テキスト150%
- 位置ずれが発生する
- Windows 7 + テキスト150%
- 位置ずれは発生しない
試したこと
動作環境: Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
上記の情報をもとにアプリケーションマニフェストを作成し高DPI対応にしてみた。
不具合は解消しなかった。
対処 > Hide(), Show()する
ウィンドウを一旦隠して、表示しなおすと対処できることが分かった。
下記のような処理を加える。
// Windows 10 「テキスト、アプリ、その他の項目のサイズを変更する」を150などにした時に位置がずれる問題の対処
this->Hide();
Application->ProcessMessages();
Sleep(50); // msec. 50: 任意の時間
this->Show();
B_hide, B_show1の後 > 下にずれている(異常)
B_hide, B_show2の後 > ずれていない (正常)
上記、実行例の実装。
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();
}
//---------------------------------------------------------------------------