0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ Builder XE4 > configuration > フォーム上の項目を変更した時にUnsaved changesを表示する仕組みの実装 > シリアライズ

0
Posted at
動作環境
C++ Builder XE4

やりたいこと

  • フォーム上に様々なコンポーネントがある
  • いずれかのコンポーネントに関して変更があったとき
    • Unsaved changesと表示したい

実装案

  • TCheckBox->Checked, TEdit->Text, TComboBox->ItemIndexすべてをString型にする
    • 「シリアライズ」と呼ぶこととする
  • フォーム表示時のシリアライズ値と、任意のタイミングのシリアライズ値の差異を検知する

実装

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 で管理されるコンポーネント
	TCheckBox *CheckBox1;
	TCheckBox *CheckBox2;
	TCheckBox *CheckBox3;
	TEdit *Edit1;
	TEdit *Edit2;
	TEdit *Edit3;
	TComboBox *ComboBox1;
	TTimer *Timer1;
	TComboBox *ComboBox2;
	TComboBox *ComboBox3;
	TLabel *L_unchanged;
	void __fastcall FormShow(TObject *Sender);
	void __fastcall Timer1Timer(TObject *Sender);
	void __fastcall ComboBoxKeyDown_general(TObject *Sender, WORD &Key, TShiftState Shift);

private:	// ユーザー宣言
	String __fastcall serializeAllComponents(void);
	String __fastcall serializeEachComponent(TControl *ctrlPtr);
	String m_onShowSerial; // Form OnShow時にシリアル
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
# endif

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)
{
	// 変更チェックのインターバル設定
	Timer1->Enabled = false;
	Timer1->Interval = 300; // msec
	Timer1->Enabled = true;

	// 全てのコンポボックスに同じ処理をする (BackSpaceキー処理)
	ComboBox1->OnKeyDown = ComboBoxKeyDown_general;
	ComboBox2->OnKeyDown = ComboBoxKeyDown_general;
	ComboBox3->OnKeyDown = ComboBoxKeyDown_general;
}
//---------------------------------------------------------------------------
// シリアルライズ関連の処理
//
String __fastcall TForm1::serializeAllComponents(void)
{
	String res = L"";
	for (int idx=0; idx < this->ControlCount; idx++) {
		res += serializeEachComponent(this->Controls[idx]);
	}
	return res;
}

String __fastcall TForm1::serializeEachComponent(TControl *ctrlPtr)
{
	if (dynamic_cast<TEdit *>(ctrlPtr) != NULL) {
		TEdit *edPtr = (TEdit *)ctrlPtr;
		return edPtr->Text;
	}
	if (dynamic_cast<TCheckBox *>(ctrlPtr) != NULL) {
		TCheckBox *chkPtr = (TCheckBox *)ctrlPtr;
		return BoolToStr(chkPtr->Checked);
	}
	if (dynamic_cast<TComboBox *>(ctrlPtr) != NULL) {
		TComboBox *cmbPtr = (TComboBox *)ctrlPtr;
		return IntToStr(cmbPtr->ItemIndex);
	}

	return L"";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	m_onShowSerial = serializeAllComponents();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	String work = serializeAllComponents();

	L_unchanged->Visible = (work != m_onShowSerial);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBoxKeyDown_general(TObject *Sender, WORD &Key, TShiftState Shift)
{
	TComboBox *cbPtr = (TComboBox *)Sender;
	if (Key == VK_BACK) {
		SendMessageA(cbPtr->Handle, CB_SHOWDROPDOWN, 0, 0); // Close ComboBox
		cbPtr->ItemIndex = -1; // deselect
	}
}
//---------------------------------------------------------------------------

動作例

ソフト起動直後
2019-03-05_19h19_05.png

項目内用を変更後
2019-03-05_19h19_24.png

項目内用を元に戻した後
2019-03-05_19h19_38.png

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?