MFCコントロール - DDV
概要
DDV (Dialog Data Validation) は、MFCアプリケーションにおけるユーザ入力データの検証機能である。
MFCアプリケーションにおけるデータ検証の基盤として、ユーザインターフェースを支援する機能である。
DDX (Dialog Data eXchange) と密接に連携して動作しており、データの整合性と有効性を確保する。
DDVの仕組みでは、UpdateData(TRUE)
メソッドを実行した (コントロールからメンバ変数にデータが転送される) 場合に、指定された検証ルールに基づいてデータの妥当性がチェックされる。
検証に失敗した場合は、自動的にエラーメッセージが表示されて、該当のコントロールにフォーカスが設定される。
検証機能として、数値の範囲、文字列の長さ、必須入力等が組み込まれている。
例えば、DDV_MinMaxInt
は整数値の範囲を検証、DDV_MaxChars
は文字列の最大長を制限する。
また、カスタム検証ロジックを実装することも可能であり、アプリケーション固有の複雑な検証要件にも対応できる。
カスタム検証ロジックは、DoDataExchange
メソッド内で独自の検証関数を呼び出す、あるいは、条件分岐を使用して実装する。
エラーハンドリングにおいては、DDVは例外を使用してバリデーションの失敗を通知するため、try-catch句を使用して例外を処理することができる。
これにより、エラーメッセージを提供する、あるいは、特定の状況下での代替処理を実装することが可能になる。
また、DDVはフォーム全体の検証も可能であり、UpdateDataメソッドの実行時に全ての検証ルールが順番にチェックされて、1つでも失敗すると処理が中断される。
これにより、データの一貫性を確保して、不正なデータがアプリケーション内部に入り込むのを防ぐことができる。
文字列の長さ
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
// 文字列の長さに検証例 (5文字以上20文字以下)
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDV_MaxChars(pDX, m_strName, 20);
DDV_MinChars(pDX, m_strName, 5);
}
数値範囲の検証
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
// 数値範囲の検証例 (0〜120)
DDX_Int(pDX, IDC_EDIT_AGE, m_nAge);
DDV_MinMaxInt(pDX, m_nAge, 0, 120);
// 浮動小数範囲の検証例 (0.0〜1000000.0)
DDX_Text(pDX, IDC_EDIT_SALARY, m_dSalary);
DDV_MinMaxDouble(pDX, m_dSalary, 0.0, 1000000.0);
}
カスタム検証
void AFXAPI DDV_EmailAddress(CDataExchange* pDX, const CString& value)
{
// コントロールからデータを取得する場合のみチェック
if (pDX->m_bSaveAndValidate) {
// 簡易的なメールアドレス確認
if (value.Find('@') == -1 || value.Find('.') == -1) {
AfxMessageBox(_T("有効なメールアドレスを入力してください"));
pDX->Fail(); // バリデーション失敗
}
}
}
void CMyDialog::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
// カスタムバリデーション 1
DDX_Text(pDX, IDC_EDIT_EMAIL, m_strEmail);
DDV_EmailAddress(pDX, m_strEmail);
// 必須入力チェック
DDX_Text(pDX, IDC_EDIT_REQUIRED, m_strRequired);
if (pDX->m_bSaveAndValidate && m_strRequired.IsEmpty()) {
AfxMessageBox(_T("この項目は必須です"));
pDX->Fail();
}
// カスタムバリデーション 2
DDX_Text(pDX, IDC_EDIT_DATA, m_strData);
if (pDX->m_bSaveAndValidate) {
// カスタム検証ロジック
if (!IsValidFormat(m_strData)) {
AfxMessageBox(_T("データ形式が不正です"));
pDX->Fail();
}
}
}