テクニカル ノート 26: DDX ルーチンおよび DDV ルーチン
[!メモ]
次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。
ここでは、をダイアログ データ エクスチェンジ (DDX) とダイアログ データ バリデーションの (DDV) のアーキテクチャについて説明します。また、DDX_ または DDV_ のプロシージャを記述し、ルーチンを使用するには ClassWizard を拡張する方法について説明します。
ダイアログ データ エクスチェンジの概要
すべてのダイアログ データの関数は、C++ で実行されます。特殊なリソースまたは魔法のマクロはありません。機構のコアは、ダイアログ データ エクスチェンジと検証したすべてのダイアログ クラスでオーバーライドされた仮想関数です。これは、このフォームに常にです:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX); // call base class
//{{AFX_DATA_MAP(CMyDialog)
<data_exchange_function_call>
<data_validation_function_call>
//}}AFX_DATA_MAP
}
AFX 特別なファイル形式のコメントは ClassWizard が、この関数内のコードを探し、編集できるようにします。コードを特殊なファイル形式のコメント外に ClassWizard と互換性のある設定する必要がない。
上の例では、フォームには <data_exchange_function_call> です:
DDX_Custom(pDX, nIDC, field);
と <data_validation_function_call> は省略可能で、フォームにです:
DDV_Custom(pDX, field, ...);
複数の DDX_/DDV_のペアは DoDataExchange の各関数に含まれる場合があります。
MFC に用意されているすべてのダイアログ データ エクスチェンジ ルーチン、およびダイアログ データ バリデーション ルーチンの一覧については、"afxdd_.h" を参照してください。
ダイアログ データでは、そのです: CMyDialog のクラス メンバー データ。は、と類似した構造体またはすべてがに格納されます。
説明
これは、"このダイアログ データを呼び出すが、のすべての機能は CWnd から派生したすべてのクラスで使用できるように、ダイアログに限定されません。
データの初期値は //{{AFX_DATA_INIT と //}}AFX_DATA_INIT のコメントをブロックの標準 C++ のコンストラクターで、通常設定されます。
CWnd::UpdateData は DoDataExchangeに呼び出しの周囲に初期化とエラー処理を行う操作です。
データ交換と検証を実行する CWnd::UpdateData をいつでも呼び出すことができます。既定では、UpdateData (true) の既定の CDialog::OnOK ハンドラーと UpdateDataで既定 CDialog::OnInitDialog (false) と呼ばれます呼び出されます。
DDV_ ルーチンは、その フィールドの DDX_ ルーチンに従う必要があります。
その動作しますか。
ダイアログ データを使用するには、次を理解する必要はありません。ただし、この方法の背後で動作を理解すると、独自の交換または検証のプロシージャを作成できます。
DoDataExchange のメンバー関数は Serialize のメンバー関数と同じようには、クラス メンバー データ from/to 外部フォーム (この場合はダイアログ コントロール) との間でデータを取得または設定する必要があります。pDX のパラメーターは、データ交換するためのコンテキストで、CObject::Serializeに CArchive のパラメーターに似ています。pDX (CDataExchange のオブジェクト) に CArchive と同じようにリダイレクトするフラグを持つ方向のフラグがあります:
!m_bSaveAndValidateがコントロールに、データの状態を読み込みます。
m_bSaveAndValidateと、そのコントロールのデータの状態を設定した場合。
検証は m_bSaveAndValidate が設定されている場合にのみ発生します。m_bSaveAndValidate の値は CWnd::UpdateDataに BOOL のパラメーターによって決まります。
CDataExchange の 3 の他のメンバーがあります:興味深い
m_pDlgWnd: コントロールを含むウィンドウ (通常、ダイアログ)。これはです DDX_ と DDV_ のグローバル関数の呼び出し元は、DDX/DDV ルーチンに "this "" 渡す必要があることを回避します。
PrepareCtrlと PrepareEditCtrl: データ交換にダイアログ コントロールを準備します。検証が失敗した場合、ストア フォーカスを設定すると、コントロールのハンドル。PrepareCtrl は nonedit のコントロールに使用され、PrepareEditCtrl は、エディット コントロールに使用されます。
[失敗]: 入力エラーをユーザーに通知メッセージ ボックスを育てた後にを呼び出す。このルーチンは最後のコントロール (PrepareCtrl/PrepareEditCtrlへの最後) にフォーカスを復元し、例外をスローします。このメンバー関数は、との両方 DDX_ DDV_ ルーチンから呼び出すことがあります。
ユーザーの拡張機能
既定の DDX/DDV 機構を拡張する方法はいくつかあります。次の操作を行うことができます。
[新しいデータ型。
CTime
[新しい交換処理 (DDX_ 場合でも、または)。
void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
[新しい検証のプロシージャ (DDV_ 場合でも、または)。
void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture); // make sure time is in the future or past
検証の手順に任意の式を渡します。
DDV_MinMax(pDX, age, 0, m_maxAge);
[!メモ]
このような任意の式では ClassWizard で編集できないため、特別なファイル形式のコメントの外に移動する必要があります (// {{AFX_DATA_MAP (CMyClass))。
DoDialogExchange のメンバー関数を混合交換と検証関数を呼び出して条件またはそのほかの有効な C++ のステートメントが格納されます。
//{{AFX_DATA_MAP(CMyClass)
DDX_Check(pDX, IDC_SEX, m_bFemale);
DDX_Text(pDX, IDC_EDIT1, m_age);
//}}AFX_DATA_MAP
if (m_bFemale)
DDV_MinMax(pDX, age, 0, m_maxFemaleAge);
else
DDV_MinMax(pDX, age, 0, m_maxMaleAge);
[!メモ]
上記のように、このようなコードは ClassWizard で編集できないため、特別なファイル形式のコメント外でのみ使用してください。
ClassWizard のサポート
ClassWizard は ClassWizard のユーザー インターフェイスに独自の DDX_ と DDV_ ルーチンを統合するため、DDX/DDV のカスタマイズのサブセットをサポートします。これを行うには、プロジェクトまたは多数のプロジェクトの特定と DDV DDX ルーチンを再利用することを計画している場合にだけ便利な計測されます。
これを行うには、特別なエントリは DDX.CLW (Visual C++ の以前のバージョンでは、APSTUDIO.INI にこの情報を格納) またはプロジェクトの .CLW ファイルで作成されます。特別なエントリは、プロジェクトの .CLW ファイルの[概要情報]セクションで、\Program の Files\Microsoft Visual Studio\Visual C++\bin のディレクトリの DDX.CLW ファイルの[ExtraDDX]セクションに入力できます。既にある DDX.CLW ファイルを作成する必要があります。特定のプロジェクトでのみ DDX_/DDV_カスタム ルーチンを使用する場合は、プロジェクト .CLW ファイルの[概要情報]セクションにエントリを追加します。多くのプロジェクトのルーチンを使用する場合は DDX.CLW の[ExtraDDX]セクションにエントリを追加します。
これらの特殊なエントリの一般的なファイル形式は次のとおりです:
ExtraDDXCount=n
n ExtraDDX 数はどこにあるか。続行する行
ExtraDDX?=<keys>;<vb-keys>; <prompt>; <type>; <initValue>; <DDX_Proc>
[;<DDV_Proc>; <prompt1>; <arg1>; [<prompt2>; <fmt2>]]
か。1 番目の– n、DDX を定義するリストを入力するを示すです。
各フィールドはによって区切られます "; " 文字。フィールドおよび目的について、次に説明します。
<keys>
すべてのダイアログがこの変数の型を制御するか = 示す一つの文字の一覧が許可されます。E = 編集
C = 2 ステート チェック ボックス
c = 三つの状態を持つチェック ボックス
R = 最初にオプション ボタンのグループ化
L = nonsorted リスト ボックス
l が = リスト ボックスを使用しました
M = コンボ ボックスの項目 (編集)
N = nonsorted ドロップの一覧
n = 並べ替えられたドロップの一覧
1 つが = 末尾で DDX の挿入がリスト (既定値) 追加の先頭に追加した場合、このコントロールが "" のプロパティを転送 DDX のルーチンに対して一般的に使用されます。
<vb-keys>
このフィールドは VBX コントロール用の 16 ビット バージョンでのみ使用されます (VBX コントロールは 32 ビット バージョンではサポートされていません)<prompt>
プロパティのコンボ ボックス (引用符なし) に設定する文字列<type>
ヘッダー ファイルに出力するには型の識別子をシングルします。さらに、上の例では DDX_Time と、これは CTime に設定されます。<vb-keys>
このバージョンでは使用されません常に空です。<initValue>
初期値は— 0 または null。これが空の場合、初期化の行では書き込まれません//{{実装ファイルのセクションの AFX_DATA_INIT。空のエントリは適切な初期化を保証するコンストラクターを持つ C++ オブジェクトにする必要があります (CString、CTimeなど)。<DDX_Proc>
DDX_ の手順の一つの識別子。C++ の関数名は "DDX_" で始まる必要がありますが、<DDX_Proc> の識別子に "" DDX_ を含めません。上の例では、<DDX_Proc> の識別子は時間です。ClassWizard ためのの実装ファイルに関数呼び出しを記述するときに{{AFX_DATA_MAP のセクション、DDX_、この名前を追加し、DDX_Time に到着します。<comment>
この DDX の変数のダイアログで示すようにコメント アウトします。ここでのテキストの設定、通常 DDX/DDV のペアが実行する操作を表すものを提供します。<DDV_Proc>
エントリの DDV の部分は省略可能です。すべての DDX のルーチンが対応する DDV ルーチンはありません。多くの場合、コピーの重要な部分として検証の結果を格納すると便利です。これは、ClassWizard がパラメーターなしでは DDV ルーチンをサポートしないため、DDV ルーチンがパラメーターを必要としない場合は、同じです。<arg>
DDV_ の手順の一つの識別子。C++ の関数名は "DDV_" で始まる必要がありますが <DDX_Proc> の識別子に "" DDX_ を含めません。
1 桁または 2 桁の DDV の引数とし、その後、:
<promptX>
編集の項目の上の場所への文字列 (アクセラレータと&の場合)<fmtX>
arg の種類のファイル形式、1 の文字d = int
u = 符号なし
17 B = long int (long)
U =、符号なし (つまり、DWORD)
浮動 f =
F = Double
= の文字列