TN026:DDX和DDV实例

备注

以下技术声明,则它在联机文档,首先包括了不更新。因此,某些过程和主题可能已过时或不正确。有关最新信息,建议您搜索议题在联机文档的索引。

此说明描述了与对话框数据交换 (ddx) 和对话框数据验证 (DDV) 体系结构。 它还描述如何编写 DDX_ 或 DDV_ 程序,以及如何扩展类向导使用您的实例。

对话框数据交换的概述

所有对话框数据函数完成对 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 定位和编辑此函数内的代码。 代码与类向导兼容应放置在特殊形式注释外部。

在上面的示例中,<data_exchange_function_call> 在窗体中:

    DDX_Custom(pDX, nIDC, field);

并 <data_validation_function_call> 是可选的并在窗体中:

    DDV_Custom(pDX, field, ...);

多个 DDX_/DDV_在每个 DoDataExchange 功能对可以包括。

为所有对话框数据交换的实例和对话框数据验证例程列表参见“afxdd_.h”随 MFC。

对话框数据是:在 CMyDialog 选件类的成员数据。 它在类似的结构或的任何内容都存储。

注释

虽然我们调用此“对话框数据,”所有功能可在从 CWnd 派生的任何选件类并不限于对话框。

数据的初始值对标准 C++ 构造函数设置,通常在与 //{{AFX_DATA_INIT 和 //}}AFX_DATA_INIT 注释的块。

CWnd::UpdateData 是在调用周围执行初始化和错误处理 DoDataExchange的操作。

可以在 + 任何 + 时间调用 CWnd::UpdateData 执行数据交换和验证。 默认情况下 UpdateData(TRUE) 在默认值 CDialog::OnOK 处理程序和 UpdateData在该默认值 CDialog::OnInitDialog调用 (错误) 调用。

DDV_ 实例应紧跟在该 字段的DDX_ 实例。

它如何工作?

您无需了解以下为了使用对话框数据。 但是,了解了如何在幕后工作将帮助您编写替换或验证程序。

DoDataExchange 成员函数十分类似于 Serialize 成员函数-到获取或设置为/从外部窗体 (在这种情况下在对话框的控件中的数据负责) from/to 在选件类的成员数据。 pDX 参数是执行上下文数据交换和类似于 CArchive 参数于 CObject::Serialize。 pDX ( CDataExchange 对象) 都有一个方向标志非常类似。CArchive 具有方向标志:

  • 如果 !m_bSaveAndValidate,然后加载数据状态到控件。

  • 如果 m_bSaveAndValidate,然后设置控件中的数据状态。

m_bSaveAndValidate 设置时,验证仅出现。 m_bSaveAndValidate 的值取决于 CWnd::UpdateData的 BOOL 参数。

还有其他三个有趣 CDataExchange 成员:

  • m_pDlgWnd:包含控件的窗口 (通常对话框)。 这是为了防止 DDX_ 和 DDV_ 全局函数调用方必须通过“this”给每个 DDX/DDV 实例。

  • PrepareCtrlPrepareEditCtrl:一个对话框控件为数据交换准备。 存储设置焦点的该控件的句柄,如果验证失败。 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);
    

    备注

    这样的任意表达式不能由类向导编辑并不应将特定格式注释外部 (// {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 编辑器,只应使用在特定格式注释外部。

类向导支持

类向导还允许将 DDX_ 和 DDV_ 实例支持 DDX/DDV 自定义项的子集类向导用户界面。 如果您计划重新使用特殊 DDX 和 DDV 实例在项目中或多个项目,这样做会只花费最好。

为此,对项进行 DDX.CLW (Visual C++ 的早期版本。APSTUDIO.INI 将此信息存储) 或项目中 .CLW 文件。 特定项中输入在项目中 .CLW 文件的 [一般信息] 部分或在 DDX.CLW 文件的 [ExtraDDX] 部分在 \Program Files\Microsoft Visual Studio\Visual C++\bin 目录中。 如果它已不存在,您可能需要创建 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 = 两个状态复选框

    c = 三种状态复选框

    R = 首先单选按钮组中

    L = nonsorted 列表框

    l = 排序列表框

    M = 组合框 (与请编辑项目)

    N = nonsorted 拉列表

    n = 排序的下拉列表

    1 =,如果 DDX 插入应添加到开头列表 (默认值是向尾) 此操作的调用“控件”属性的 DDX 实例通常使用。

  • <vb-keys>
    此字段在 16 位产品仅用于 VBX 控件 (VBX 控件在 32 位产品不支持)

  • <prompt>
    放置的字符串在属性组合框 (而不是引号)

  • <类型>
    单个类型的标识符可以发出在标头文件。 在上面的示例我们的中的 DDX_Time,这将设置为 CTime。

  • <vb-keys>
    不使用此版本,并且应始终为空

  • <initValue>
    初始值— 0 或空白。 如果是空的,则初始化行在//不会编写{实现文件中的 AFX_DATA_INIT 部分。 应为具有构造函数来确保正确的初始化的 C++ 对象使用空项 (如 CStringCTime,等等)。

  • <DDX_Proc>
    DDX_ 程序的唯一标识符。 C++ 函数名。<DDX_Proc> 标识符必须从“DDX_ 开始,”,但不包括“DDX_”。 在上面的示例中,<DDX_Proc> 标识符是时间。 在函数调用中的实现文件中的类向导编写{AFX_DATA_MAP 部分,它将追加此名称来 DDX_,从而达到 DDX_Time。

  • <comment>
    注释显示在变量的对话框与此 DDX。 将您需要此处的所有文本和通常提供描述 DDX/DDV 执行的操作对的操作。

  • <DDV_Proc>
    项的 DDV 部分是可选的。 并非所有的 DDX 实例具有相应的 DDV 实例。 通常,包括验证阶段作为调用的组成部分会更方便。 这通常是这样,当您的 DDV 实例不需要任何参数,则,因为类向导不支持 DDV 实例没有任何参数。

  • <arg>
    DDV_ 程序的唯一标识符。 C++ 函数名。<DDX_Proc> 标识符必须从“DDV_”开头,但是,不包括“DDX_”。

后跟 1 或 2 DDV 参数:

  • <promptX>
    放置的字符串在编辑项目中 (与&的快捷键的)

  • <fmtX>
    个参数类型的格式字符,则

    d = int

    u = 未签名

    D = 长 int (即长)

    U = 长时间未签名 (即 DWORD)

    f = 浮动

    F = 二进制文件

    = 的字符串

请参见

其他资源

由Number "技术说明

技术说明按类别