Edited at

c++ builder > TImageが来るからそこ空けるように、の実装 v0.1, v0.2

More than 1 year has passed since last update.


動作環境

C++ Builder XE4



やりたいこと


  • TImageは普段は隠れている (右側の画面外)

  • ある条件でTImageを表示する


    • その場所より下にある複数のコンポーネントを下にずらす




v0.1 Tag使用


実装案


  • 特定のTagの値を持つコンポーネントだけずらす


実装


Unit1.cpp

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

#include <vcl.h>
#pragma hdrstop

#include <pngimage.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
Image1->Picture->LoadFromFile(L"AD2.png");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_toLeftClick(TObject *Sender)
{
static const int kTag_move = 79;
static const int kMargin_down = 10;

// 1. Image1の高さ分、コンポーネントを下にずらす

for(int idx=0; idx < this->ComponentCount; idx++) {
TComponent *aPtr = this->Components[idx];
if (aPtr->Tag != kTag_move) {
continue;
}

TControl *ctlPtr = (TControl *)aPtr;
ctlPtr->Top += ( Image1->Height + kMargin_down );
}

this->Height += Image1->Height;

// 2. Image1を左に移動
Image1->Left = 16;
}
//---------------------------------------------------------------------------



v0.1の結果


移動前

qiita.png


移動後

qiita.png


別の案

Tagは他の用途に使う場合もある。

その場合は、TControl *のリストにて、移動対象となるコンポーネントのポインタを格納する。

それらに対してのみ移動処理を実装すればいい。


v0.2 TControl *のリストで指定


実装


Unit1.cpp

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

#include <vcl.h>
#pragma hdrstop

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

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
Image1->Picture->LoadFromFile(L"AD2.png");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_toLeftClick(TObject *Sender)
{
static const int kMargin_down = 10;

static TControl *targetList[] = {
Panel1,
Button1,
Label2,
StringGrid1,
};
int targetCount = sizeof(targetList) / sizeof(targetList[0]);

// 1. Image1の高さ分、コンポーネントを下にずらす

for(int idx=0; idx < targetCount; idx++) {
TControl *aPtr = targetList[idx];
aPtr->Top += ( Image1->Height + kMargin_down );
}

this->Height += ( Image1->Height + kMargin_down );

// 2. Image1を左に移動
Image1->Left = 16;
}
//---------------------------------------------------------------------------


targetList[]の定義は関数内でしているが、他の場所で定義するのが良い。

Tag指定よりこちらがいい点は、コードで意図が分かること。

Tag指定の場合は、フォームデザインでTagを確認しないと、どれが移動対象のコンポーネントか分からない。ソースリーディングしにくくなる。

別の場所でtargetList[]を宣言しようとしたが、あきらめた。

targetList[]に格納するポインタはFormShow処理以降に格納する必要がある。

それを考えると処理が複雑になる。


検索用キーワード

(追記 2018/10/18)


  • そこのけそこのけ