S-JIS[2006-09-14/2006-09-15]

ダイアログデータ⇔iniファイル

iniファイルにはCWinApp::GetProfile系やWriteProfile系の関数を使って読み込んだり書き込んだりできますが、扱いたいデータが多くなると、似たようなコードを保存用と取得用に二種類書かないといけなくなって、面倒です。

そこで、これを1つにまとめる方法を考えてみました。
(読み書きしたい変数群を、一度しかコーディングしないところがミソ)


ここでは、ダイアログのデータをまとめてiniファイルにセーブ・ロードすることを目的とします。

ダイアログ上のエディットボックスやチェックボックス等のコントロールを、DDX(Dialog Data eXchange)を使ってダイアログクラスのメンバー変数にすることは多いと思います。
そして その多くなった変数を扱うのが厄介なので…。

MyDlg.h:

class CMyDlg : public CDialog
{
〜
	void IniSave(){ IniSerialize(FALSE); } //iniファイルへ保存
	void IniLoad(){ IniSerialize(TRUE); }  //iniファイルから読み込み
private:
	void IniSerialize(BOOL bLoad);
〜
}

MyDlg.cpp: [/2006-09-15]

#define	INI_SECT	"DATA"

//CString読み書き用(オーバーロード)
static void GetWriteProfile(CWinApp *pApp, CString &var, LPCTSTR name, BOOL bLoad)
{
	if(bLoad){
		var = pApp->GetProfileString(INI_SECT, name, "");
	}else{
		pApp->WriteProfileString(INI_SECT, name, var);
	}
}

//int読み書き用(オーバーロード)
static void GetWriteProfile(CWinApp *pApp, int &var, LPCTSTR name, BOOL bLoad)
{
	if(bLoad){
		var = pApp->GetProfileInt(INI_SECT, name, 0);
	}else{
		pApp->WriteProfileInt(INI_SECT, name, var);
	}
}

void CMyDlg::IniSerialize(BOOL bLoad)
{
	CWinApp *pApp = AfxGetApp();
#define SERIALIZE(var) GetWriteProfile(pApp,var,#var,bLoad)

	SERIALIZE(m_edtData1);	//エディットボックス(CString m_edtData1)
	SERIALIZE(m_edtData2);

	SERIALIZE(m_chkData1);	//チェックボックス(BOOL m_chkData1)
	SERIALIZE(m_chkData2);

#undef SERIALIZE
}

iniファイルとの読み書き用にGetWriteProfileという関数を用意しました。
CStringやint用にオーバーロードされている(関数名は同じで引数の型だけ違う)のがポイントで、これにより、どういう型であっても呼び出す側は全く同じ形でコーディングできます。オーバーロード万歳!(笑)

また、CWinApp::GetProfile*やWriteProfile*では セクション(上記のINI_SECT)とエントリー(上記のname)が必要ですが、エントリー名についてはメンバー変数名をそのまま使っています。
SERIALIZEマクロの「#var」というのが、変数名を文字列に変換している箇所です。マクロの引数の先頭に「#」を付けると、変数ではなく文字列に展開されるのです。プリプロセッサ万歳!(笑)

SERIALIZE(m_edtData1)

GetWriteProfile(pApp,m_edtData1,"m_edtData1",bLoad)

まあ、実際に書かれたiniファイルの中を見てしまうと、ちょっと変かもしれませんが…(苦笑)

なおかつ、GetWriteProfileへメンバー変数を渡すところは 参照渡し(引数の宣言で「&」を付けている)にしています。
これにより、関数の中で普通の変数に読み書きするのと同じコーディングで 呼び出し元の変数を読み書きできます。これはポインターを使っても実現できるけれど、こういう時は参照渡しの方が分かり易い。参照万歳!(笑)


上記の関数を実際に使うには、以下のようにします。


VC++ページへ戻る / 技術メモへ戻る
メールの送信先:ひしだま