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

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
```

### 概要

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

### 前バージョン

- [C++ Builder 10.2 Tokyo > color > UI > 色選択 + RGB値入力 [一つのセット版]](https://qiita.com/7of9/items/5e3ad36dd4df94631521)


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

### 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で色を変更できるようになった。

![2019-07-03_16h13_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/225d05f7-90f0-aeab-999c-4760da496d5c.png)


### 他のコード

#### Unit2

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

- [C++ Builder 10.2 Tokyo > color > UI > 色選択 + RGB値入力 [一つのセット版]](https://qiita.com/7of9/items/5e3ad36dd4df94631521)