C++ Builder 10.2 Tokyo > color > UI > 色選択 + RGB値入力 [複数のセット版] > Tag: 操作対象コンポーネントの格納と利用


動作環境
RAD Studio 10.2 Tokyo Update 3

概要

  • 下記UIを用意した
    • A. TColorBoxからの色選択
    • B. RGB値の直接入力

前バージョン

上記は「一つのセット」の実装。
これを「複数のセット」へ拡張した。

Tag: 操作対象コンポーネントの格納と利用

コードを共通化するために、Tagプロパティを使う。

  1. Tagプロパティに操作対処のコンポーネントのポインタを格納
  2. Tagプロパティからポインタを取得し、それに対して操作をする

Unit1

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TButton *B_select1;
    TShape *Shape1;
    TEdit *E_RGBvalue1;
    TLabel *Label1;
    TButton *B_select2;
    TShape *Shape2;
    TEdit *E_RGBvalue2;
    TLabel *Label2;
    void __fastcall B_selectXClick(TObject *Sender);
    void __fastcall FormShow(TObject *Sender);
    void __fastcall E_RGBvalueXExit(TObject *Sender);
    void __fastcall E_RGBvalueXKeyDown(TObject *Sender, WORD &Key, TShiftState Shift);


private:    // ユーザー宣言
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

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

#include <vcl.h>
#pragma hdrstop

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

/*
Note:
Tagプロパティにそのコンポーネントが操作するコンポーネントのポインタを格納する
共通実装において、そのポインタを使って操作を行う
*/

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
void __fastcall TForm1::FormShow(TObject *Sender)
{
    E_RGBvalue1->MaxLength = 6; // R,G,B値それぞれ00..FF
    E_RGBvalue1->Text = L"FFFFFF";
    E_RGBvalue2->MaxLength = 6; // R,G,B値それぞれ00..FF
    E_RGBvalue2->Text = L"FFFFFF";

    // Tagを使ったコンポーネント操作用
    //   1用
    E_RGBvalue1->Tag = (NativeInt)Shape1;
    B_select1->Tag = (NativeInt)E_RGBvalue1;
    //   2用
    E_RGBvalue2->Tag = (NativeInt)Shape2;
    B_select2->Tag = (NativeInt)E_RGBvalue2;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_selectXClick(TObject *Sender)  // 共通実装
{
    Form2->ShowModal();
    if (Form2->ModalResult != mrOk) {
        return;
    }

    TColor acol = Form2->ColorBox1->Selected;
    int Rval = GetRValue(acol);
    int Gval = GetGValue(acol);
    int Bval = GetBValue(acol);

    TButton *btPtr = (TButton *)Sender;
    TEdit *edPtr = (TEdit *)btPtr->Tag;
    if (edPtr != NULL) {
        edPtr->Text = String().sprintf(L"%02X%02X%02X", Rval, Gval, Bval);
        edPtr->OnExit(edPtr);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::E_RGBvalueXExit(TObject *Sender)  // 共通実装
{
    TEdit *edPtr = (TEdit *)Sender;

    // char型を扱うため、ここでAnsiStringにする必要がある (Stringだとwchar_tになる)
    AnsiString astr = AnsiString(edPtr->Text);   // e.g. FFFF00

    int tmp;
    int Red, Green, Blue;
    char *endptr;

    AnsiString wrk = astr.SubString(1, 6);
    tmp = strtol(wrk.c_str(), &endptr, 16);

    if (*endptr == 0x00) {
        Red   = strtol(astr.SubString(1, 2).c_str(), /*endptr=*/NULL, 16);
        Green = strtol(astr.SubString(3, 2).c_str(), /*endptr=*/NULL, 16);
        Blue  = strtol(astr.SubString(5, 2).c_str(), /*endptr=*/NULL, 16);
    } else {
        Red = 255;
        Green = 255;
        Blue = 255;
        edPtr->Text = L"FFFFFF";
    }

    TShape *shPtr = (TShape *)edPtr->Tag;
    if (shPtr != NULL) {
        shPtr->Brush->Color = (TColor)RGB(Red, Green, Blue);
        shPtr->Pen->Color = (TColor)RGB(Red, Green, Blue);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::E_RGBvalueXKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)  // 共通実装
{
    if (Key == VK_RETURN) {
        TEdit *edPtr = (TEdit *)Sender;
        edPtr->OnExit(Sender);
    }
}
//---------------------------------------------------------------------------

イベント設定

  • B_selectXClick
    • B_select1のOnClick
    • B_select2のOnClick
  • E_RGBvalueXExit
    • E_RGBValue1のOnExit
    • E_RGBValue2のOnExit
  • E_RGBValueXKeyDown
    • E_RGBValue1のOnKeyDown
    • E_RGBValue1のOnKeyDown

実行例

それぞれのボタンとTEditで色を変更できるようになった。

他のコード

Unit2

以下と同じ.h, .cppファイル。