LoginSignup
0
0

More than 5 years have passed since last update.

C++ Builder XE4, 10.2 Tokyo > Forms > Windows 10 Invisible borderを含まないHeight, Width取得クラス > CUtilFormSize_noInvisibleBorder (Windows 7, 8.1, 10対応)

Last updated at Posted at 2018-05-07
動作環境
RAD Studio 10.2 Tokyo Update 3
C++ Builder XE4
秀丸エディタ Version 8.79
Windows 7 Pro (32bit)
Windows 8.1 Pro (64bit)
Windows 10 v1709 (64bit)

関連

Windows 7, 8.1, 10でのフォームHeight, Width取得

Windows 10からinvisible borderが導入されたため、Windows 7, 8.1, 10上でのソフト動作(位置調整)が変わってしまう。

それを避けるためgetVisibleWindowSize()を実装したが、様々なフォームから使用するにはソース分離する方がいいだろう。

下記においてソース分離した。

code

UtilFormSize_noInvisibleBorder.h
//---------------------------------------------------------------------------

#ifndef UtilFormSize_noInvisibleBorderH
#define UtilFormSize_noInvisibleBorderH
//---------------------------------------------------------------------------

/*
Windows 10から導入された「Invisible border」。
Windows 7, 8.1, 10で同じ位置調整処理を使えるようにするため、Invisible borderを含まない
サイズを返す関数を用意した。
*/

class CUtilFormSize_noInvisibleBorder
{
private:
    static void __fastcall getVisibleWindowSize(TForm *formPtr, TRect *rectPtr);
public:
    static int __fastcall GetHeight(TForm *formPtr);
    static int __fastcall GetWidth(TForm *formPtr);
    // テスト関数
    static void __fastcall Test_showHeightAndWidth(TForm *formPtr);
};

#endif
UtilFormSize_noInvisibleBorder.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UtilFormSize_noInvisibleBorder.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

/*
v0.1 2018/05/07
    - Test_showHeightAndWidth()追加
    - GetWidth()追加
    - GetHeight()追加
    - getVisibleWindowSize()追加
*/

//---------------------------------------------------------------------------
// private関数
//
/*static*/void __fastcall CUtilFormSize_noInvisibleBorder::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)の方を返す
    //
    // !!!ただしWindows 10の場合、FormShow時には正しい値を返さない!!!
    // FormShow後に実行すること

    rectPtr->left = arect_inv.left;
    rectPtr->top = arect_inv.top;
    rectPtr->right = arect_inv.right;
    rectPtr->bottom = arect_inv.bottom;
}

//---------------------------------------------------------------------------
// public関数
//
/*static*/ int __fastcall CUtilFormSize_noInvisibleBorder::GetHeight(TForm *formPtr)
{
    // !!!Windows 10の場合、FormShow時には正しい値を返さない!!!
    // FormShow後に実行すること

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

    TRect arect;

    getVisibleWindowSize(formPtr, &arect);
    return arect.bottom - arect.top;
}

/*static*/ int __fastcall CUtilFormSize_noInvisibleBorder::GetWidth(TForm *formPtr)
{
    // !!!Windows 10の場合、FormShow時には正しい値を返さない!!!
    // FormShow後に実行すること

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

    TRect arect;

    getVisibleWindowSize(formPtr, &arect);
    return arect.right - arect.left;
}

//---------------------------------------------------------------------------
// テスト関数
//
/*static*/ void __fastcall CUtilFormSize_noInvisibleBorder::Test_showHeightAndWidth(TForm *formPtr)
{
    if (formPtr == NULL) {
        return; // error
    }

    int hei = CUtilFormSize_noInvisibleBorder::GetHeight(formPtr);
    int wid = CUtilFormSize_noInvisibleBorder::GetWidth(formPtr);

    String msg = String().sprintf(L"%d x %d", hei, wid);
    ShowMessage(msg);
}

使用例

Test_showHeightAndWidth()の実装を参考にする。

注意事項

Windows 10においてはFormShow時にフォームのHeight, Widthが正しく取得できない。

FormShow後にHeightとWidthを取得すると良い (下記参照)。

0
0
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
0