MFCコントロール - コントロールの更新
概要
DDX (Dialog Data Exchange) は、MFCにおけるユーザインターフェースとソースコード間のデータ交換を自動化する機能である。
DDXの基本的な仕組みとしては、ユーザインターフェースのコントロールとクラスのメンバ変数を紐づけ、その間でのデータ交換を自動的に行う。
この仕組みにより、開発者は手動でのデータ変換やフォーマット処理を記述する必要がなく、効率的な開発が可能になる。
データ交換の方向性については、CWnd::UpdateData
メソッド / CDialog::UpdateData
メソッドの引数で制御する。
UpdateData(TRUE)を指定した場合はコントロールに入力された値からメンバ変数へ、UpdateData(FALSE)を指定した場合はメンバ変数に格納された値をコントロールへとデータが移動する。
例えば、ユーザが入力したテキストを取得する場合は、UpdateData(TRUE)を実行して、計算結果をコントロールに表示する場合はUpdateData(FALSE)を使用する。
※注意
UpdateData
メソッドのデフォルト引数はTRUE
であることに注意する。
DDXのメリットとして、データ型の自動変換や値の検証 (バリデーション) 機能が組み込まれていることが挙げられる。
例えば、テキストボックスに入力された文字列を整数型のメンバ変数に変換する場合、自動的に型変換が行われて、無効な入力があった場合はエラーメッセージが表示される。
また、DDXと組み合わせてDDV (Dialog Data Validation) を使用することにより、高度な入力値の検証が可能となる。
例えば、数値の範囲チェックや必須入力チェック等を実装することができる。
DDX (Dialog Data Exchange)
DDXの実装において、DoDataExchange関数内でDDX_TextやDDX_Int等のマクロを使用して、コントロールIDとメンバ変数の関連付けを行う。
// 一般的なコントロール向け
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CONTROL, m_control); // 一般的なコントロールの紐付け
DDX_Text(pDX, IDC_EDIT1, m_strName); // 文字列向け
DDX_Int(pDX, IDC_EDIT2, m_nAge); // 整数向け
DDX_Check(pDX, IDC_CHECK1, m_bActive); // チェックボックス向け
DDX_Radio(pDX, IDC_RADIO1, m_nRadio); // ラジオボタングループ向け
DDX_Scroll(pDX, IDC_SCROLLBAR, m_nScroll); // スクロールバー向け
}
// リストコントロール向け
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
DDX_LBString(pDX, IDC_LISTBOX, m_strList); // リストボックスの文字列
DDX_CBString(pDX, IDC_COMBO, m_strCombo); // コンボボックスの文字列向け
DDX_LBIndex(pDX, IDC_LISTBOX, m_nIndex) // リストボックスの選択インデックス
DDX_CBIndex(pDX, IDC_COMBO, m_nIndex) // コンボボックスの選択インデックス
DDX_LBStringExact(pDX, IDC_LISTBOX, m_str) // リストボックス (完全一致)
DDX_CBStringExact(pDX, IDC_COMBO, m_str) // コンボボックス (完全一致)
}
DDX (Dialog Data Exchange) の使用例
以下の例では、ボタンを押下した時、UpdateData()でIDC_EDIT1に入力された文字列を変数m_xvEdit1に格納している。
次に、変数m_xvEdit1の文字列を変数m_xvEdit2にコピーして、UpdateData(FALSE)で変数m_xvEdit2の文字列をIDC_EDIT2に反映させている。
// CMyDialog.hファイル
class CMyDialog : public CDialogEx
{
// ...
private:
CString m_xvEdit1;
CString m_xvEdit2;
// ...
};
// CMyDialog.cppファイル
CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/) : CDialog(CMyDialog::IDD, pParent), m_xvEdit1(_T("")), m_xvEdit2(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_xvEdit1);
DDX_Text(pDX, IDC_EDIT2, m_xvEdit2);
}
void CMyDialog::OnBnClickedButton()
{
// UpdateData(TRUE)でDDX変数を更新
UpdateData();
// m_xvEdit1の内容をm_xvEdit2に代入
m_xvEdit2 = m_xvEdit1;
// UpdateData(FALSE)でDDX変数の内容をコントロールに反映
UpdateData(FALSE);
}
下図に、上記のサンプルコードの実行例を示す。
IDC_EDIT1にABCDEを入力し、Button1を押すと、IDC_EDIT2に反映される。