cppBuilder
TForm
geometry

C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」変更状態でフォームのHeight, Widthを設定する実装

動作環境
C++ Builder XE4

関連

C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」 > 中(M)や大(L)の場合にウィンドウサイズが変化する

実装

FormのプロパティScaledをfalseにする方法などもあるかもしれない。

以下ではScaledをtrueのまま対応する一つの方法を取る。

code

SetSizeRelativeToPixelsPerInch()を追加した。

UtilScreen.h
//---------------------------------------------------------------------------

#ifndef UtilScreenH
#define UtilScreenH

//---------------------------------------------------------------------------

/*
フォームのサイズ変更関連を処理する
*/

class CUtilScreen {
private:
    //

public:
    static void __fastcall CUtilScreen::AutoSizeSetting(TForm *formsPtr[], int num);
    static void __fastcall CUtilScreen::SetSizeRelativeToPixelsPerInch(TForm *formPtr, int height, int width);
};

#endif
UtilScreen.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <memory>
#include "UtilScreen.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

#define DEBUG_DO_PRINT // デバッグ出力

/*
v0.8 2017/11/21
    - SetSizeRelativeToPixelsPerInch()追加
v0.7 2017/10/09
    - fix bug: 引数のNULLチェック漏れ
        + fix AutoSizeSetting()
v0.6 2015/11/12
    - DEBUG_PRINT マクロを DEBUG_DO_PRINT に変更した。DEBUG_PRINTは関数マクロとして使われる例があるため
v0.5 2015/11/03
    - AutoSizeSetting()を実装した。
*/

static void debug_outputDebugString(String prefix, String msg)
{
    // あとでまとめてデバッグ出力をコメントアウトするため、関数にしている。

#ifdef DEBUG_DO_PRINT
    String work = L"UtilScreen >" + prefix + L": " + msg;
    OutputDebugString(work.c_str()); // @ debug_outputDebugString
#endif
}

/* static*/void __fastcall CUtilScreen::AutoSizeSetting(TForm *formsPtr[], int num)
{
    if (formsPtr == NULL) {
        String msg = L"Line36 > Error [formsPtr] is NULL";
        debug_outputDebugString(/*prefix=*/L"CUtilScreen", msg);
        return;// error
    }

    // 基準となるノートPCの解像度
    int noteW = 1367;
    int noteH = 768;

    int myW = Screen->Monitors[0]->Width;
    int myH = Screen->Monitors[0]->Height;

    // 小さい場合も対応することにしたので、以下はコメントにした
//  if (myW <= noteW && myH <= noteH) {
//      return;
//  }

    float ratioH = (float)myH / (float)noteH;
    float ratioW = (float)myW / (float)noteW;

    int setRatio;
    if (ratioH < ratioW) {
        setRatio = ratioH * 100; // 少数第二位まで扱う
    } else {
        setRatio = ratioW * 100;
    }

    for(int idx=0; idx < num; idx++) {
        formsPtr[idx]->ScaleBy(setRatio, 100);
    }

}

/*static*/void __fastcall CUtilScreen::SetSizeRelativeToPixelsPerInch(TForm *formPtr, int height, int width)
{
    /*
    「テキストやその他の項目の大きさの変更」にて「小」から変更された状態でフォームサイズ変更処理を行うと
    フォームが期待通りのサイズにならない。下記にて比率を考慮したサイズ設定を行う。
    */

    static const int kDefault_PixelsPerInch = 96;

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

    int ppi = formPtr->PixelsPerInch;
    formPtr->Height = height * ppi / kDefault_PixelsPerInch;
    formPtr->Width = width * ppi / kDefault_PixelsPerInch;
}

使用コード例

FormShow()にて使う。

Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "UtilScreen.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int dpi  = this->PixelsPerInch;
    ShowMessage(IntToStr(dpi));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    CUtilScreen::SetSizeRelativeToPixelsPerInch(this, /*height=*/338, /*width=*/651);
}
//---------------------------------------------------------------------------

検索用キーワード

(追記 2018/10/19)

- 拡大