📄 18.2.2 自定义属性.txt
字号:
18.2.2 自定义属性
当前 Clock控件是每隔 l秒更新一次时间的显示,接下来,我们给 Clock控件增加一个自定义的属性:时间间隔,在用户设置了该属性的值以后, Clock控件就按照用户指定的时间间隔值来更新显示的时间。
这时同样需要利用 ClassWizard来为 Clock控件添加属性,并且也是选择 ClassWizard 对话框上的 Automation选项卡,然后单击【 Add Prope向】按钮,将弹出增加属性对话框。在该对话框中有几项内容,其中 External name (外部名称〉是在像 VB这样的集成开发环境中所看到的控件的属性名称,而 Variable name (变量名称)是在 VC++集成开发环境中开发这个控件时使用的该控件类的成员变量。也就是说,在开发程序中使用 Variable name访问控件的属性,而在外部使用该控件时,使用的是 External name访问控件的属性。这里,我们将新添加的时间间隔属性的外部名称设置为 Interval,类型选择为 short类型,变量名称自动被设置为 ill_interval, ClassWizard为该控件自动增加了一个通知函数: OnIntervalChanged (如图 18.31所示),当在外部修改该属性时,这个函数将被调用。
&'2.... ...圃,: 31 OK Iypc: --工lc.o回自
v...........:
ZE--gntev叩ulngcd
自楠,幅幅嗣嗣,,--一他…一一一牛一一一}叫一~ 'ì
俨斟鹏咂圣王液觅到 r'Go刷= .011川
图 18.31为 Clock控件增加一个名为 IntervaJ的自定义属性
可以看到,在添加属性对话框上为我们提供了三个单选按钮,但这时只有两个选项可供选择,默认选择的是 Member variable,当选择该选项后, ClassWizard会为该属性生成一个成员变量,并生成一个通知函数,正如图 18.31所示的那样;如果选择 GetJSet methods 选工页,这时添加属性对话框就变成了如图 18 .3 2所示的样子。可以看到,这时在添加属性对话框中就没有成员变量和通知函数这两个选项了, ClassWizard会为该属性自动生成两个函数: SetInterval和 GetInterval。在程序中,如果想要设置 Interval属性的值,可以调用
详
职肌
Setlnterval函数:如果想要得到该属性的值,可以调用 GetIn terva!函数。但在控件内部,
如果想要保存 Interval这个属性的值,需要我们自己定义一个成员变量来实现。刚才我们
己经看到,如果选择 Member variable选项, ClassWizard会自动生成一个这样的成员变量,本例保持默认设置,即选择 Member variable选工页。
k翌生>J><'"' ":飞磊圃 E
阳时甲: tnte......1 "3 [二豆3 Jype: I'hort 3 旦旦」
,G.' r .... IGetlnlervl1
曲tt =*,,: IS'川叫
腼...-甸嗣·
r .叫俨蛐巾,回础。画画矗豆豆量
e-......
图 18.32选择 GetJSet methods选项时的添加属性对话框
然后,单击添加属性对话框上的【 OK】按钮完成 Interval属性的添加,井单击 ClassWizard对话框上的【 OK】按钮关闭 ClassWizard对话框。这时,在 VC开发环境中,在 ClassView选项卡上,可以看到LDClock接口中又增加了一个属性: Interval,并且在 CClockCtrl类中增加了一个函数: OnlntervalChanged。当 Interval这一外部属性被修改时,就会调用这个 OnIntervalChanged函数。该函数的默认实现代码如例 18-8所示。
例 18-8
飞roid CClockCtrl : :OnlntervalChanged() // TODO : Add not工 f工 cation handler code SetMod工 f工 edFlag() ;
可以看到,在此函数中调用了一个名为 SetModifiedFlag的函数,根据字面的意思,可以猜测到该函数是用来设置属性被修改的标记。另外,可以发现, ClassWizard还为 CClockCtrl类提供了一个成员变量: m_interval, 其定义代码如例 18-9所示。
f9IJ 18-9
// Dispatch maps / / {{AFX_D工 SPATCH(CClockCtrl) short m_interval; afx_msg void OnlntervalChanged(); / /} }AFX一DISPATCH DECLARE_D工 SPATCH_MAP ( )
可以看到,增加的 m interval和 OnIntervalChanged函数的定义都位于 CClockCtrl类的调度映射中。前面已经介绍过,调度映射主要是为了让外部应用程序可以方便地访问控件
"I 679
ActiveX撞件
第18
的属性和方法。接下来,我们就在 OnlntervalChanged函数中根据用户输入的时间间隔值控制 Clock控件的显示更新。具体代码如例 18-10所示。例 18-10
void CClockCtrl : :OnlntervalChanged()
// TODO: Add notification handler code
if (m_工nterval<O II m_interval>6000)
m_lnιerval=1000;
else
m_interval=m_interval / l000*1000;
KillTimer(工) ;
SetTimer(l , m_interval , NULL) ;
SetModifiedFlag() ;
.
因为时间间隔不能为负数,也不能太大。所以在 OnIntervalChanged函数中,首先对 m interval变量的值进行判断,如果用户设置的时间间隔属性值小于 0,或者大于 6000,则就将这个问隔值设置为 1000。否则,进行调整,即对用户输入的值取整,得到一个整数的秒数。接下来,调用KillTimer函数销毁先前设置的定时器(其标识是1),然后再次调用 SetTimer函数利用新的时间间隔设置定时器,定时器标识仍为1,时间间隔用Clock控件的m interval属性值来设置。
利用Build命令生成最新的Clock控件,然后利用ActiveX Control Test Container容器测试该控件。在利用【Edit'飞Insert New Control...】命令插入该控件后,为了测试控件的属性,需要选中该控件,然后单击【Control\lnvoke Met'hods. ..】菜单项,这时将显示如图 18.33所示的对话框。
hrmrt!I"C叫1m咄1岳1
..由..41..
l飞 F '-.!斗 Er 泣豆1
1;1-. I
'__.t.. r....tv
d Sltti ,Vfι回 l
帽
..‘"且
he..ti_
he.,ti_ :::JI !ζ再也飞{,.J
图 18.33 Invoke Methods对话框
680 I ~~t协
vc..深λ详解
i~..mil~6m_ll 一一一一一」 在此对话框中有一个方法名称 CMethodName)下
Bo. ckC olor Q'ropGet)
Bo.ckC olor Q'ropPut) 拉列表,在此列表中列出了当前控件提供的方法,如
ForeColor Q'ropGet)
For.Color Q'ropPut) 图 18.34所示。
Int ervo.l Q'r opGe t) Intervo.l Q'ropPut) 如果想要得到某个属性值,应该选择PropGet类型图 18.34 Clock控件当前提供的方法 的方法;如果想要设置某个属性的值,则应该选择
PropPut类型的方法。这里我们想要设置 Clock控件的 Interval属性的值,因此应该选择 Interval C PrOpPut)项,并在随后出现的对话框的Parameter编辑框中输入数值: 2000,单击【SetValue】按钮,这时就把Interval属性的值设置为2000了,如图 18.35所示。
Ah-M htE-σ-nEV IY n,z, ut 单且」
1;1... I
A--叮3
Vù".l
。
山
也'π俨
Par..ter Pv..ter
lm∞ lVT_I2 二j
B.tvn
,
....,ti幅 .
....,ti...
阳在你/íè1d
图 18.35调用Interval CPropPut)方法设置该属性的值
但是,这时这个属性值仍未生效,需要单击【Invoke】按钮才行。之后就会发现Clock控件显示的时间每隔2秒跳动一次,说明设置生效了。
接下来,再在VB中测试Clock控件。打开先前的VBTest程序,在窗体上选中Clock控件,然后在属性面板中就可以看到Interval属性,其默认值是-个很大的负数,这主要是因为我们还没有给这个属性值进行初始化,这里我们将该属性值设置为3000。这时,读者可以注意窗体中Clock控件显示的时间值的变化,可以看到它是每隔3秒跳动一次。
下面,我们希望能够通过控件的属性表单设置控件的 Interval这个自定义属性。也就是说,在控件的属性表单中增加一个属性页,在该属性页上提供对时间间隔属性进行设置的接口。在VB环境中,可以看到这时Clock控件的属性表单如图 18.29所示,正好有一个名称为 General的属性页当前还没有被使用,于是,就可以在这个属性页上增加一个编辑框,让用户根据需要输入时间间隔属性的值。
因此,关闭 VBTest程序,回到 VC++开发界面,切换到 Clock工程的 ResourceView 选项卡,打开IDD_PROPPAGE_CLOCK对话框资源,并删除该对话框资源中已有的内容。然后在其中放置一个静态文本控件,将其Catpion属性设置为:"hte凹al: "。再放置一个编辑框控件,将其m属性设置为: IDC_EDIT_INTERVAL.让用户在此编辑框中输入想要设置的时间间隔值。这时的IDD_PROPPAGE_CLOCK对话框资源如图 18.36所示。
" ‘ I 681
第18章ActiveX搜件
;山".1: C~H … j
图 18.36修改后的IDD]ROPPAGE_CLOCK对话框资源
然后,为新添加的编辑框控件关联一个成员变量,这可以利用 ClassWizard来完成。在该控件上单击鼠标右键,从弹出的快捷菜单中选择【ClassWiz缸d...】菜单项,并打开随后出现的ClassWizard对话框中的MemberVariables选项卡,单击【AddV.红iable...】按钮,这时将出现增加成员变量对话框,在此对话框中,将该成员变量的名称设置为: m_updateInterval,类型设置为: short。在该对话框下面有一个 "Optional property name"选工页,该选项用来指定可选的属性名称。在为对话框上某个控件关联成员变量的时候, MFC 还为我们提供了这样一个选项,让控件在关联一个成员变量的同时,还可以与一个属性进行关联,也就是说,我们在开发ActiveX控件时,在为对话框上某个控件关联成员变量的同时,还可以为其选择一个属性与这个控件进行关联,这个属性可以是标准的属性,也可以是自定义的属性。本来我们就是想要通过这个编辑框控件,让用户输入时间间隔值,因此在这里就可以与控件的 Interval属性相关联,但应注意,这里关联的名称是属性的外部名称,并不是在代码类中使用的成员变量的名称,因此,这里在Optional property name控件中应该指定为Interval。结果如图 18.37所示。
m"F?t
B.am-t-
‘田
m-ue
,』
F.'L
.
-nv
寸
d
S础10ry:
VarI.ble JVpe: 一 3
33
IShort
QP畸on.1 property neme:
iz jlmml
Descrlp咽。n: . 饰。"响th ranle Y1IlIde1lon
.
图 18.37为编辑框控件增加一个关联的成员变量和关联的属性
单击【OK】按钮关闭添加成员变量对话框,并再次单击【OK】按钮关闭ClassWizard 对话框。这时,可以发现在CClockPropPage类的DoDataExchange函数中添加了如下面例 18-11所示代码中两行加灰显示的代码。
侈IJ 18-11 ////////////////////////////////////////// ///////////////////////////// / / CClockPropPage: :DoDataExchange -Moves data between page and properties
void CClockPropPage : : DoDataExchange (CDataExchange* pDX)
682 I胁~ ..
II {{AFX一DATA_MAP(CClockPropPage)
DDP_Text(pDX,工 DC_EDIT_INTERVAL, ffi_updateInterval,一T ( "工 nterval") );
DDX_Text(pDX , IDC_EDIT_INTERVAL , ffi_update工 nterval) ;
II }}AFX_DATA_MAP
DDP_PostProcessing(pDX) ;
这样,我们不但为编辑框控件关联了一个成员变量: m_updateInterval,同时还将其与 Clock控件的一个属性: Interval关联起来了。但是,我们并没有为编辑框控件与 Clock控件属性的关联编写任何代码,这都是 ClassWizard为我们自动实现的。
利用 Build命令生成最新的 Clock控件,然后再次利用 ActiveX Control Test Container 容器测试该控件。当插入该控件后,在该控件上单击鼠标右键,并从弹出的快捷菜单中选择【特性】菜单项,从而打开 Clock控件的属性页,在 General选项卡上的编辑框控件中输入 3000 (如图 18.38所示),然后单击【应用】按钮,这时读者可以注意到, Clock控件显示的时间是每隔 3秒跳动一次。
ιl川归时m,~础·型理-h叫 III@. Ira
嗣j
图 18.38在 ActiveX Control Test Container容器中对 Clock控件的 lnterval属性进行测试
这里,我们是在 Clock控件自身的属性表单中对该控件的Interval属性进行设置。同样地,也可以在 VB中进行这种测试,读者可以自行完成。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -