LoginSignup
0
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-16
動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
   - code v0.2に関して動作確認済

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

qiita.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

無関係の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

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: 範囲外エラー

0
1
0

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
0
1