c++ builder XE4, 10.2 Tokyo > 格子状配置のTCheckBoxのCheckedを行列で取得する > Tagプロパティの使用

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
   - code v0.2に関して動作確認済
```

以下のように格子状配置のTCheckBoxのCheckedを行列で取得する。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/c8c57c25-6486-5ef8-7d75-6ddd4b9906b3.png)

Tagを使ってみた。

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

/*
Tagの設定 ( 3行3列 )
101 102 103
201 202 203
301 302 303
*/

void __fastcall TForm1::B_readClick(TObject *Sender)
{
	bool mtrx[3][3];

	for(int idx=0; idx < this->ComponentCount; idx++) {
		if (dynamic_cast<TCheckBox *>(this->Components[idx]) == NULL) {
			continue;
		}

		TCheckBox *srcPtr = (TCheckBox *)this->Components[idx];
		int tag = srcPtr->Tag;

		if (tag < 101 || tag > 303) { // 対象となるTCheckBoxの識別 (TODO: Tag値以外の識別)
			continue;
		}
		int col = tag % 100 - 1;
		int lin = tag / 100 - 1;
		mtrx[lin][col] = srcPtr->Checked;
	}

	int nop=1; // for breakpoint ( to check mtrx[][] )
}
//---------------------------------------------------------------------------
```

上記のint nop=1;の行で停止して、mtrx[][]を見ると以下となった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/036f68c1-3c89-ab54-fee2-bffd1ec51998.png)

無関係のTCheckBoxを無視する識別方法は要検討。

10行10列の読取りにいいだろうか。


## code v0.2

上記のコードから以下のように変更してみた。

- TFormポインタ指定
- 親コンポーネント名指定
- line, column位置指定

こうすることで、任意の位置のChecked状態を取得しやすくなる。

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

bool __fastcall TForm1::getChecked(TForm *formPtr, String parentName, int lineIdx, int columnIdx, int *errCodePtr)
{
	if (errCodePtr == NULL) {
		return false;
	}

	int li, ci; // 0始まり
	String prntNam;
	bool found = false;
	TCheckBox *srcPtr;

	for(int idx = 0; idx < formPtr->ComponentCount; idx++) {
		if (dynamic_cast<TCheckBox *>(formPtr->Components[idx]) == NULL) {
			continue;
		}

		prntNam = formPtr->Components[idx]->GetParentComponent()->Name;
		if (prntNam != parentName) {
			continue;
		}

		srcPtr = (TCheckBox *)formPtr->Components[idx];
		ci = srcPtr->Tag % 100 - 1;
		li = srcPtr->Tag / 100 - 1;

		if (li == lineIdx && ci == columnIdx) {
			found = true;
			break;
		}
	}

	if (found) {
		*errCodePtr = NO_ERR;
		return srcPtr->Checked;
	}

	*errCodePtr = ERR_OUT_OF_RANGE;
	return false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_checkPanel1Click(TObject *Sender)
{
	bool res;

	String prntNam = L"Panel1";
	int errCode;
	String msg;

	for(int li = 0; li < 3; li++) { // li: line index
		msg = L"";
		for(int ci = 0; ci < 3; ci++) {	// ci: columne index
			res = getChecked(this, prntNam, li, ci, &errCode);
			if ( errCode == TForm1::NO_ERR ) {
				msg = msg + L" " + BoolToStr(res);
			} else {
				msg = msg + L" x ";
			}
		}
		OutputDebugString(msg.c_str());
	}
}
void __fastcall TForm1::B_checkPanel2Click(TObject *Sender)
{
	bool res;

	String prntNam = L"Panel2";
	int errCode;
	String msg;

	for(int li = 0; li < 3; li++) { // li: line index
		msg = L"";
		for(int ci = 0; ci < 3; ci++) {	// ci: columne index
			res = getChecked(this, prntNam, li, ci, &errCode);
			if ( errCode == TForm1::NO_ERR ) {
				msg = msg + L" " + BoolToStr(res);
			} else {
				msg = msg + L" x ";
			}
		}
		OutputDebugString(msg.c_str());
	}
}
//---------------------------------------------------------------------------
```

```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 で管理されるコンポーネント
	TPanel *Panel1;
	TPanel *Panel2;
	TCheckBox *CheckBox1;
	TCheckBox *CheckBox2;
	TCheckBox *CheckBox3;
	TCheckBox *CheckBox4;
	TCheckBox *CheckBox5;
	TCheckBox *CheckBox6;
	TCheckBox *CheckBox7;
	TCheckBox *CheckBox8;
	TCheckBox *CheckBox9;
	TCheckBox *CheckBox10;
	TCheckBox *CheckBox11;
	TCheckBox *CheckBox12;
	TCheckBox *CheckBox13;
	TButton *B_checkPanel1;
	TButton *B_checkPanel2;
	void __fastcall B_checkPanel1Click(TObject *Sender);
	void __fastcall B_checkPanel2Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	enum {
		NO_ERR = 0,
		ERR_OUT_OF_RANGE,
	};

	bool __fastcall getChecked(TForm *formPtr, String parentName, int lineIdx, int columnIdx, int *errCodePtr);

	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/1cb8dfc0-8513-35ab-551c-155ce9036615.png)

### checkPanel1ボタンを押した時の結果

```txt:結果
デバッグ出力:  -1 0 -1 プロセス Project1.exe (2392)
デバッグ出力:  -1 -1 -1 プロセス Project1.exe (2392)
デバッグ出力:  -1 0 -1 プロセス Project1.exe (2392)
```

### checkPanel2ボタンを押した時の結果

```txt:結果
デバッグ出力:  -1 0 x  プロセス Project1.exe (2392)
デバッグ出力:  -1 -1 x  プロセス Project1.exe (2392)
デバッグ出力:  x  x  x  プロセス Project1.exe (2392)
```

-1: Checked
x: 範囲外エラー