分享
 
 
 

DDX和DDV方法

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

DDX和DDV方法

本文主要介绍DDX和DDV的体系结构,本文也帮助您了解DDX或DDV的过程以及如何扩展ClassWizard,使它可以使用用户的过程。下面我们首先来看一下对话框数据交换。请注意,在上面的两个过程中,关键的问题在于虚函数的重载。我们经常会在我们用ClassWizard生成的代码中看到下面的代码:

void CMyDialog::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX); // call base class

//{{AFX_DATA_MAP(CMyDialog)

<data_exchange_function_call>

//}}AFX_DATA_MAP

}

其中AFX是由ClassWizard控制的,只有包括在AFX中间的代码才可以由ClassWizard管理,如果用户不希望让一些东西让ClassWizard管理了,那就把这些东西移出AFX就可以了。但是,通常的情况下还是不这样做的好。上面代码中还有一段没有写出来,那就是<data_exchange_function_call>,它的形式可以是DDX_Custom(pDX, nIDC, field),或是DDV_Custom(pDX, field, ...);,所有的关于DDX和DDV的定义在文件'afxdd_.h'中定义。函数初始化的定义在类的构造函数中的//{{AFX_DATA_INIT和//}}AFX_DATA_INIT之间。

CWnd::UpdateData函数是我们经常使用的,我们经常在它后面的值中取一些true或者false之类的值,那让我们来看看,如果是true,它都做了些什么。它实际上进行的就是数据交换。我们一般不用了解下面的所说的数据交换过程一样可以使用对话框,但是如果我们能够了解一点,那当然要好多了。我们可以把DoDataExchange成员函数看成是Serialize(串行化)成员函数,反正两都都是将数据送入类中,或把数据从类中送出。我们在上面代码中一定看到了一个pDX的东西,它是一个参数,它是用于进行数据交换的参数,我们上面已经知道了在UpdateData中要传送一个参数,表示方向,那我们看看pDX中表示数据传输方向(这个方向就是表示数据究竟是从类中传输出来呢,还是向类传送进去呢):

如果m_bSaveAndValidate为假,将数据传输到相应的控件上去,数据传输出类了。

如果m_bSaveAndValidate为真,将数据传输到类中来,数据传输进类了!

在设置了m_bSaveAndValidate之后,验证(数据有效性的)过程才得以进行。

下面有几个函数可是不能不说:

m_pDlgWnd: 它指是包括当前控件的窗口,它用来防止DDX_和DDV_的全局调用;

PrepareCtrl:是用于准备进行数据交换的对话框控件,它返回一个窗口句柄。如果验证过程失败,就得用这个句柄使原来的窗口继续获得焦点。请注意:PrepareCtrl用于准备非编辑性的控件,对于可以进行输入和编辑的控件请使用PrepareEditCtrl;

Fail: 我们验证过程失败时,调用Fail过程,这个函数的主要作用就是恢复对原来窗口的焦点,保持原来窗口中的输入与选择内容,发出一个Exception。

我们可以通过下面几个方法扩展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);

下面的验证就是验证输入的年纪是不是在0到最大年纪(对人来说可能是500岁)之间:

DDV_MinMax(pDX, age, 0, m_maxAge);

上面的这些代码不能由ClassWizard管理,所以要放在//{{AFX_DATA_MAP(CMyClass))之外。

下面是一些有条件的验证,它的意思,我想在我就不多嘴了,看这篇文章的也多少知道几个英文,大家看英文自己也会明白的。

//{{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,那不更好吗。ClassWizard支持DDX和DDV的子集,通过让ClassWizard管理DDX和DDV,我们会得到一些方便。特别在重复使用的时候更是如此。如果希望实现这个功能,可以在DDX.CLW中或工程的.CLW中进行编译,加入相应的函数入口。在工程的.CLW中,将用户自定义的函数入口写在[General Info]段中,也可以在DDX.CLW的[ExtraDDX]段中加入相应的代码,但是请注意,一定要把DDX.CLW放在\Program Files\DevStudio\SharedIDE\bin目录下。当然,如果DDX.CLW不存在,那只有用户自己创建它了。如果你只希望在你的工程中使用特定的函数入口,将相应的函数入口加入工程的.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 = edit

C = two-state check box

c = tri-state check box

R = first radio button in a group

L = non-sorted list box

l = sorted list box

M = combo box (with edit item)

N = non-sorted drop list

n = sorted drop list

如果DDX需要插入在列头上,则要使用1。它一般用于传输控制属性的DDX过程。

<vb-keys> 此域用于传输16位VBX控件的一些情况,对于32位的产品,根本就不支持VBX;

<prompt> = 放置在属性组合框中的字符串;

<type> = 在头文件中出现的单个标记。在上例中,它应该被设置为CTime;

<vb-keys> = 为空

<initValue> = 初值为0或为空。如果为空,不需要在初始化行//{{AFX_DATA_INIT内进行初始化。只有当成员为类的时候才好使用这个选项,因为对于类,有类的初始化函数进行初始化,可是对于其它类型还是要进行初始化的;

<DDX_Proc> = DDX过程的标识符,DDX过程的C++函数名必须以DDX开始,但这个DDX不应该包括在<DDX_Proc>标识符中。上例中的<DDX_Proc>应该为Time,ClassWizard可以在将函数写入{{AFX_DATA_MAP段时加上DDX。

<comment> = 注释。用户愿意放什么就可以放什么。

<DDV_Proc> DDV过程标识符,不是所有的DDX过程后面都要有DDV过程,为了方便起见,可以将DDV过程作为集成化传输的一部分。你可以写上这一项,但是不加参数,ClassWizard不会将不带参数的DDV加入代码中的。DDV过程也要有DDV作为前缀,但是不必加上,因为ClassWizard可以自己加上。下面两个是DDV参数:

<promptX> = 放置在编程项目上的字符串,可以使用&作为加速键

<fmtX> = 参数类型的格式字符,它们有:

d = int

u = unsigned

D = long int (that is, long)

U = long unsigned (that is, DWORD)

f = float

F = double

s = string

例子大家可以参考VC自己带的例子chkbook。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有