LoginSignup
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-10-20
動作環境
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)

  • そこのけそこのけ

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
1