動作環境
C++ Builder XE4
内容
- E_maxA:TEdit, E_stepA:TEdit, CHK_AutoA:TCheckBox がある
- CHK_AutoAがチェックされているとき
- E_maxA変更時にE_stepAに5で除算した値を代入する
コンポーネント間の連動を行う
検討事項
今後、上記のようなセットをN個(N>3)扱う時、処理を共通化するといい場合があるかもしれない
実装 v0.1
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "editex"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// コンポーネントアドレスの格納と関数の設定
// セットA
E_maxA->Tag = (int)E_stepA;
E_maxA->HelpContext = (int)CHK_AutoA;
E_maxA->OnExit = NE_maxExit_general; // 関数設定
E_maxA->OnKeyDown = NE_maxKeyDown_general; // 関数設定
CHK_AutoA->Tag = (int)E_stepA;
CHK_AutoA->HelpContext = (int)E_maxA;
CHK_AutoA->OnClick = CHK_AutoClick_general; // 関数設定
// セットB
E_maxB->Tag = (int)E_stepB;
E_maxB->HelpContext = (int)CHK_AutoB;
E_maxB->OnExit = NE_maxExit_general; // 関数設定
E_maxB->OnKeyDown = NE_maxKeyDown_general; // 関数設定
CHK_AutoB->Tag = (int)E_stepB;
CHK_AutoB->HelpContext = (int)E_maxB;
CHK_AutoB->OnClick = CHK_AutoClick_general; // 関数設定
}
//---------------------------------------------------------------------------
// { 共用の関数 (XXX_general)
//
void __fastcall TForm1::updateMajorStep_general(TEdit *maxPtr)
{
// 共用: 複数のコンポーネントで使用する
// Senderのプロパティ
// Tag: stepのアドレス
// HelpContext: CHK_Autoのアドレス
if (maxPtr == NULL) {
return; // error
}
TCheckBox *chkAutoPtr = (TCheckBox *)maxPtr->HelpContext;
if (chkAutoPtr->Checked == false) { // AutoがONかどうか
return;
}
TEdit *stepPtr = (TEdit *)maxPtr->Tag;
// 計算式を代入 (例として5で割る)
int step = StrToIntDef(maxPtr->Text, 0);
int wrk = step / 5;
stepPtr->Text = IntToStr(wrk);
}
void __fastcall TForm1::NE_maxExit_general(TObject *Sender)
{
// 共用: 複数のコンポーネントで使用する
updateMajorStep_general((TEdit *)Sender);
}
void __fastcall TForm1::NE_maxKeyDown_general(TObject *Sender, WORD &Key, TShiftState Shift)
{
// 共用: 複数のコンポーネントで使用する
if (Key != VK_RETURN) {
return;
}
updateMajorStep_general((TEdit *)Sender);
}
void __fastcall TForm1::CHK_AutoClick_general(TObject *Sender)
{
// 共用: 複数のコンポーネントで使用する
// Senderのプロパティ
// Tag: stepのアドレス
// HelpContext: maxのアドレス
if (Sender == NULL) {
return;
}
TCheckBox *chkPtr = (TCheckBox *)Sender;
TEdit *stepPtr = (TEdit *)chkPtr->Tag;
if (chkPtr->Checked) {
stepPtr->Color = cl3DLight;
stepPtr->ReadOnly = true;
updateMajorStep_general(/*neMaxPtr=*/(TEdit *)chkPtr->HelpContext);
} else {
stepPtr->Color = clWhite;
stepPtr->ReadOnly = false;
}
}
// } 共用の関数 (XXX_general)
//---------------------------------------------------------------------------
動作例
Autoにチェックを付けて、Maxに値を代入した後 (AとBについて)
備考
- エラー処理は不十分かもしれない
- 処理の中身(5で除算)は見えにくくなってはいる
- updateMajorStep_general()の中身は5で除算する以外の処理もしたいかもしれない
- => 共通処理を緩和する
- => 共通処理を複数用意する
- など
実装 v0.2
- 変更
- プロパティと関数の設定を共通化
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "editex"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// // コンポーネントアドレスの格納
// // セットA
// E_maxA->Tag = (int)E_stepA;
// E_maxA->HelpContext = (int)CHK_AutoA;
// E_maxA->OnExit = NE_maxExit_general;
// E_maxA->OnKeyDown = NE_maxKeyDown_general;
// CHK_AutoA->Tag = (int)E_stepA;
// CHK_AutoA->HelpContext = (int)E_maxA;
// CHK_AutoA->OnClick = CHK_AutoClick_general;
// // セットB
// E_maxB->Tag = (int)E_stepB;
// E_maxB->HelpContext = (int)CHK_AutoB;
// E_maxB->OnExit = NE_maxExit_general;
// E_maxB->OnKeyDown = NE_maxKeyDown_general;
// CHK_AutoB->Tag = (int)E_stepB;
// CHK_AutoB->HelpContext = (int)E_maxB;
// CHK_AutoB->OnClick = CHK_AutoClick_general;
// コンポーネントアドレスの格納
setRelatedComponentsAndFunctions(E_maxA, E_stepA, CHK_AutoA);
setRelatedComponentsAndFunctions(E_maxB, E_stepB, CHK_AutoB);
}
void __fastcall TForm1::setRelatedComponentsAndFunctions(TEdit *maxPtr, TEdit *stepPtr,
TCheckBox *chkPtr)
{
if (maxPtr == NULL || stepPtr == NULL || chkPtr == NULL) {
ShowMessage("[DEBUG 38] address is NULL");
return;
}
// コンポーネントアドレスの格納
maxPtr->Tag = (int)stepPtr;
maxPtr->HelpContext = (int)chkPtr;
maxPtr->OnExit = NE_maxExit_general;
maxPtr->OnKeyDown = NE_maxKeyDown_general;
chkPtr->Tag = (int)stepPtr;
chkPtr->HelpContext = (int)maxPtr;
chkPtr->OnClick = CHK_AutoClick_general;
}
//---------------------------------------------------------------------------
// { 共用の関数 (XXX_general)
//
void __fastcall TForm1::updateMajorStep_general(TEdit *maxPtr)
{
// 共用: 複数のコンポーネントで使用する
// Senderのプロパティ
// Tag: stepのアドレス
// HelpContext: CHK_Autoのアドレス
if (maxPtr == NULL) {
return; // error
}
TCheckBox *chkAutoPtr = (TCheckBox *)maxPtr->HelpContext;
if (chkAutoPtr->Checked == false) { // AutoがONかどうか
return;
}
TEdit *stepPtr = (TEdit *)maxPtr->Tag;
// 計算式を代入 (例として5で割る)
int step = StrToIntDef(maxPtr->Text, 0);
int wrk = step / 5;
stepPtr->Text = IntToStr(wrk);
}
void __fastcall TForm1::NE_maxExit_general(TObject *Sender)
{
// 共用: 複数のコンポーネントで使用する
updateMajorStep_general((TEdit *)Sender);
}
void __fastcall TForm1::NE_maxKeyDown_general(TObject *Sender, WORD &Key, TShiftState Shift)
{
// 共用: 複数のコンポーネントで使用する
if (Key != VK_RETURN) {
return;
}
updateMajorStep_general((TEdit *)Sender);
}
void __fastcall TForm1::CHK_AutoClick_general(TObject *Sender)
{
// 共用: 複数のコンポーネントで使用する
// Senderのプロパティ
// Tag: stepのアドレス
// HelpContext: maxのアドレス
if (Sender == NULL) {
return;
}
TCheckBox *chkPtr = (TCheckBox *)Sender;
TEdit *stepPtr = (TEdit *)chkPtr->Tag;
if (chkPtr->Checked) {
stepPtr->Color = cl3DLight;
stepPtr->ReadOnly = true;
updateMajorStep_general(/*maxPtr=*/(TEdit *)chkPtr->HelpContext);
} else {
stepPtr->Color = clWhite;
stepPtr->ReadOnly = false;
}
}
// } 共用の関数 (XXX_general)
//---------------------------------------------------------------------------
動作結果はv0.1と同じため、省略。