動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
- code v0.2に関して動作確認済
以下のように格子状配置のTCheckBoxのCheckedを行列で取得する。
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[][]を見ると以下となった。
無関係の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
checkPanel1ボタンを押した時の結果
結果
デバッグ出力: -1 0 -1 プロセス Project1.exe (2392)
デバッグ出力: -1 -1 -1 プロセス Project1.exe (2392)
デバッグ出力: -1 0 -1 プロセス Project1.exe (2392)
checkPanel2ボタンを押した時の結果
結果
デバッグ出力: -1 0 x プロセス Project1.exe (2392)
デバッグ出力: -1 -1 x プロセス Project1.exe (2392)
デバッグ出力: x x x プロセス Project1.exe (2392)
-1: Checked
x: 範囲外エラー