C++ Builder XE4 > geometry > 右配置のTEditのフォントサイズを拡大時、左配置のTChartを残りスペースで描画するサイズに落とす > ScaleBy()での処理


動作環境
C++ Builder XE4

関連

上記の処理は自動計算部分が煩雑であり、コンポーネントが多数ある場合には向かない処理である。

下記で別方法を掲示する。

処理概要

  • ボタン押下時、TChart以外を拡大する
    • SVGA, 4K UHD対応を視野に入れて
  • ScaleBy()を使い、パネルのサイズを変更する
    • それに伴い、パネル上のコンポーネントは自動的に拡大される

v0.1 > 拡大ボタンでの処理

フォームデザイン

Anchorsを下記のようにして、フォームサイズの変更に対応できるようにしている。
(フォームサイズを拡大縮小時、グラフサイズが拡大縮小するようにしている)

  • PNL_topLeft
    • akLeft, akTop, akRight
  • Chart1
    • akLeft, akTop, akRight, akBottom
  • B_large
    • askTop, askRight
  • akTop, akRight, akBottom

実装

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

static float s_curFactor = 1.0; // 拡大率

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_largeClick(TObject *Sender)
{
    int preH = this->Height;
    int preW = this->Width;

    this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す

    s_curFactor *= 1.10;

    this->ScaleBy(100 * s_curFactor, 100);

    // 元の高さ、幅に戻すことで、パネルのコンポーネントのサイズだけを拡大できる
    // (結果として、TChartは小さくなる)
    this->Height = preH;
    this->Width = preW;
}
//---------------------------------------------------------------------------

結果

起動直後

B_largeボタンを3回クリック後

さらにB_largeボタンを3回クリック後

備考

  • ScaleBy()での処理なので、フォントが汚くなる
    • フォントが汚いのを避けたい場合は、他の方法を考案すること

v0.2 > TComboBoxでのサイズ指定

実装

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

static float s_curFactor = 1.0; // 拡大率

enum {
    FONT_SMALL = 0,
    FONT_MEDIUM,
    FONT_LARGE,
    FONT_EXTRA_LARGE,
    FONT_HUGE,
};

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CMB_fontSizeChange(TObject *Sender)
{

    int preH = this->Height;
    int preW = this->Width;

    this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す

    switch(CMB_fontSize->ItemIndex){
    case FONT_SMALL:
        s_curFactor = 1.00; // 結果を見て調整する
        break;
    case FONT_MEDIUM:
        s_curFactor = 1.20; // 結果を見て調整する
        break;
    case FONT_LARGE:
        s_curFactor = 1.40; // 結果を見て調整する
        break;
    case FONT_EXTRA_LARGE:
        s_curFactor = 1.60; // 結果を見て調整する
        break;
    case FONT_HUGE:
        s_curFactor = 1.80; // 結果を見て調整する
        break;
    }

    this->ScaleBy(100 * s_curFactor, 100);

    // 元の高さ、幅に戻すことで、パネルのコンポーネントのサイズだけを拡大できる
    // (結果として、TChartは小さくなる)
    this->Height = preH;
    this->Width = preW;

}
//---------------------------------------------------------------------------

結果

Small選択時 (起動直後)

Large選択時

Huge選択時

備考

  • 全画面表示で実行すると位置計算を失敗する
    • FontSizeのTComboBoxが行方不明になる
  • 拡大縮小を繰返すうちに、ボタンのサイズが意図より小さくなる
    • 誤差が蓄積するのかもしれない

v0.3 > 拡大、縮小を繰返した場合の誤差の抑止

v0.2のコードでは拡大・縮小を繰返した場合、ボタンの横幅が小さくなるなどの誤差が顕著に見られる。

その対策として以下の変更をすると誤差が小さくなるようだ。

//  this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
    this->ScaleBy(100, 100 *s_curFactor); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す