0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ Builder XE4 > Windows 7, 8.1, 10 のウィンドウサイズ情報を見る

Last updated at Posted at 2018-04-25
実装環境
C++ Builder XE4

関連

ウィンドウサイズを知る

Windows 10特有の「invisible border」。

Windows 7, 8.1, 10で同じようにウィンドウ配置するためには、invisible borderを含まないvisibleなウィンドウサイズ情報を知る必要がある。

WPF and WIndows 10. Invisible border around windows?

answered May 18 '16 at 23:59
mikew

You can get the offests by using a combination of the normal GetWindowRect function and the use of the DwmGetWindowAttribute function, together with the DWMWA_EXTENDED_FRAME_BOUNDS parameter.

上記の関数を使ってウィンドウ情報を調べてみる。

code

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)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TRect arect_inv;
    RECT arect_nrm;

    HWND hwnd1 = this->Handle;
    HWND hwnd2 = this->Handle;

    GetWindowRect(hwnd1, &arect_nrm);
    DwmGetWindowAttribute(hwnd2, DWMWA_EXTENDED_FRAME_BOUNDS, &arect_inv, sizeof(TRect));

	String msg;
	msg = String().sprintf(L"GetWindowRect: top:%d, bottom:%d, left:%d, right:%d",
		arect_nrm.top, arect_nrm.bottom, arect_nrm.left, arect_nrm.right);
	msg += L"\r\n";
	msg += String().sprintf(L"DwmGetWindowAttribute: top:%d, bottom:%d, left:%d, right:%d",
		arect_inv.top, arect_inv.bottom, arect_inv.left, arect_inv.right);

    ShowMessage(msg);
}
//---------------------------------------------------------------------------

実行結果

Windows 7

qiita.png

Windows 8.1

qiita.png

Windows 10

qiita.png

知見

  • Windows 7ではDwmGetWindowAttribute()が0を返す
  • Windows 8.1と10ではDwmGetWindowAttribute()からvisibleのウィンドウサイズが得られそう

code > OSによらずvisible ウィンドウサイズを得る

Unit1.c
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TRect arect;

	GetVisibleWindowSize(this, &arect);

	int width = arect.bottom - arect.top;
	int height = arect.right - arect.left;
	String msg = String().sprintf(L"left:%d top:%d W:%d H:%d",
		arect.left, arect.top, width, height);

	ShowMessage(msg);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::GetVisibleWindowSize(TForm *formPtr, TRect *rectPtr)
{
	TRect arect_inv;
	RECT arect_nrm;

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

	GetWindowRect(formPtr->Handle, &arect_nrm); // (1)
	DwmGetWindowAttribute(formPtr->Handle, DWMWA_EXTENDED_FRAME_BOUNDS, &arect_inv, sizeof(TRect)); // (2)

	// for Windows 7
	if (arect_inv.left == 0 && arect_inv.top == 0 && arect_inv.Bottom == 0 && arect_inv.right == 0) {
		// DwmGetWindowAttribute()が0を返すためGetWindowRect()の結果を使う
		rectPtr->left = arect_nrm.left;
		rectPtr->top = arect_nrm.top;
		rectPtr->right = arect_nrm.right;
		rectPtr->bottom = arect_nrm.bottom;
		return;
	}

	// for Windows 8.1, Windows 10
	//   Windows 8.1では(1)と(2)は同じ定義
	//   Windows 10ではinvisible borderにより(1)と(2)の結果が異なる
	//   invisible borderのサイズを含まない(2)の方を返す
	rectPtr->left = arect_inv.left;
	rectPtr->top = arect_inv.top;
	rectPtr->right = arect_inv.right;
	rectPtr->bottom = arect_inv.bottom;
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?