网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读

源代码在线查看: 18.5 . 属性的持久性.txt

软件大小: 956 K
上传用户: kzdai22
关键词: TXT VC 目录
下载地址: 免注册下载 普通下载 VIP

相关代码

				18.5 . 属性的持久性
				在VB中打开己有的VBTest程序,并打开Clock控件自身的属性表单,在General属性页上将Interval属性值设置为3∞0,井在其颜色属性页上分别修改BackColor和ForeColor属性的值。然后保存当前VB工程,之后关闭该工程。接着在VB中再次打开该工程,读者将会看到Clock控件的背景色和前景色仍是上次工程关闭前的颜色,没有发生改变,说明 Clock控件的背景色和前景色属性的值已经被保存下来了,也就是说,这两个属性实现了持久性。
				下面再来看看 Interval这个属性,之前己经将该属性的值设置为 3000,可是这时在 General选项卡中看到该属性的值是一个很大的负数,说明该属性的值没有被保存下来。作为一个ActiveX控件,其属性都应该具有持久性。因为在使用ActiveX控件时,用户希望本次对该控件设置的属性值,在下次再打开程序时,该控件的这些值仍能保持不变。如果当再次打开程序时,该ActiveX控件的属性值还需要从头再设置一遍的话,这对用户来说是非常不方便的。所以,我们应该让Clock控件的Inte凹al这一自定义属性也具有持久性,当程序保存控件各标准属性的值时,用户对Clock控件设置的Interva1属性值也应被保存。
				因此,关闭 VBTest程序,回到VC++开发环境中。可以看到,在CClockCtrl类中有一个 DoPropExchange函数,该函数提供了对控件属性持久性的支持。可以在此函数中为每一个具有持久性的自定义属性调用以 "PX"开头的函数。 MFC为一些基本类型都提供了一个以"PX"开头的函数,例如PX Short、 PX_Long等。前面我们将Interval属性值的类型定义为 sho口,因此这里可以调用PX Short函数,让该属性具有持久性。该函数的
				
				" ‘ I 689 
				第 18章 ActiveX撞佯 
				原型声明如下所示: 
				BOOL PX_Short( CPropExchange* pPX, LPCTSTR pszPropName, short& sValue, short sDefault) ; 
				PX-Short函数有四个参数,其含义分别如下所述。 
				. pPX 
				指向 CPropExchange对象的一个指针。在本例中, DoPropExchange函数正好有一个同样类型的参数,所以可以直接将该参数传递给 PX_Short函数的第一个参数。 
				. pszPropName 
				提供给外部程序使用的属性的名称。 
				. sValue 
				与属性相关联的类的成员变量。 
				. sDefault 
				属性默认值。也就是说,调用 PX Short函数让属性具有持久性时,还可以为该属性指定一个默认值。
				下面,就在 CClockCtrl类的 DoPropExchange函数的最后添加下面这条语旬,让Interval属性具有持久性,井设置其默认值为 1000。 
				PX_Short(pPX, .工 nterval", m_interval, 1000);
				利用 Build命令生成最新的 Clock控件,然后在 VB程序中测试该控件。打开已有的 VBTest程序,打开 Clock控件自身的属性表单,在其 General属性页上,可以看到Interval属性具有初始值: 1000。我们将该属性值设置为 2000,再次保存该 VB工程,并关闭。然后重新打开该工程,发现 Clock控件显示的时间仍是每隔 1秒跳动一次,但是打开该控件的 General属性页后,会发现 Interval属性值是 2000。同时,在 VB提供的属性面板上,可以看到 Interval属性值确实也是 2000,这说明这个 Interval属性值已经被保存下来了,但为什么 Clock控件显示的时间还是每隔 1秒跳动一次呢?这主要是因为我们先前在 CClockC位l类的 OnCreate函数 (上述例 18-3所示代码)中调用 SetTimer函数创建定时器时,将定时器的时间间隔直接指定为 100。这个数值,所以这时 Clock控件仍以 1秒为间隔来更新。这里,我们将该行代码修改为下面这条语句: 
				SetTimer(l ,m_interval ,NULL) ; 
				也就是说,不为定时器指定一个具体的更新时间间隔数值,而是由与 Clock控件的 Interval属性相关联的成员变量 :mJntewal来控制这个时间间隔值。
				利用 Build命令生成最新的 Clock控件,然后在 VB中打开己有的 VBTest测试工程,这时,将会看到 Clock控件显示的时间是每隔 2秒跳动一次了。这就说明Interval属性的值确实被保存下来了,并且在程序中应用生效了。对于用户来说,如果每次设置了控件的属性之后,以后再次重新启动程序时,先前设置的属性值仍能保持不变,他们就会认为该控件具有较好的易用性。
				接下来,在 VB开发环境下,打开 Clock控件的属性表单,井切换到颜色属性页上,然后改变该控件的 BackColor属性,同时注意 VB属性面板上该属性的变化,例如,我们
				690 I ~~~ 
				vc科深λ详解
				在Clock控件的颜色属性页上将 Clock的背景色设置为黄色,可以看到W属性面板上 BackColor属性同时也变为黄色。同样,也可以在 Clock控件的属性页上改变该控件的前景色,会发现该属性改变的同时,在VB属性面板中 ForeColor属性也作了相应的调整。这说明我们在利用Clock控件自身提供的属性表单中的属性页修改该控件的BackColor和 ForeColor属性的同时,该控件通知了它的容器,这里即 VB程序,后者就更新了属性面板
				中相应属性的设置。
				上面是对Clock控件标准属性的修改,现在让我们看看对该控件自定义属性的修改会不会产生同样的效果。继续在VB开发环境中,先拖动VB提供的属性面板上的垂直滚动条,使Interval属性显示在我们的视线中,然后在Clock控件的属性表单的General属性页上,修改自定义属性: Interval的值,这时该属性的值是2000,我们将其修改为10∞,单击【应用】按钮,这时,可以看到Clock控件显示的时间变成1秒跳动一次了,但是在VB的属性面板上, Interval属性显示的值仍是2∞0,这种情况就会对用户造成迷惑:到底这个Interval属性的值是1000,还是2000呢?这主要是因为控件自定义属性的值发生改变后,没有通知容器,让容器做出相应的调整而造成的后果。
				根据前面的知识,我们知道,当 Interval这个属性的值发生改变时,会调用 Clock控件,即 CClockCtrl对象的OnIntervalChanged函数。因此,我们可以在这个函数内部通知控件的容器,告诉后者Interval这个属性的值己经发生改变了。这里可以调用COleControl类的成员函数: BoundPropertyChanged,该函数将通知容器绑定的属性值己经发生了改变。 BoundPropertyChanged函数的原型声明如下所示: 
				void BoundPropertyChanged( DISP工o dispid l; 
				该函数有一个参数,该参数是控件的一个绑定属性的调度E。
				在Clock.odl文件中,可以找到如例 18-18所示的这段代码。 
				91J 18-18 
				
				/ / Primary d工spatch interface for CClockCtrl 
				[ uuid(A5C7E77E-7399-4525-B3AD-02C6EOAA5D23l , helpstring ( "0工spatch interface for Clock Control ") , hidden ] dispinterface一DClock 
				. 
				properties: // NOTE -ClassWizard will maintain property information here. // Use extreme caution when edit工ng this section. / / ({AFX一ODL_PROP(CClockCtrl) [id(DISPID_BACKCOLORl , bindable, requestedit] OLE_COLOR BackColor; [id(D工SP工D_FORECOLOR) , bindable, requestedit] OLE_COLOR Forecolor; [id(ll] short Interval; I/ }}AFX_ODL_PROP 
				
				methods : // NOTE -ClassWizard will maintain method工nformation here. // Use extreme caution when editing this section. 
				"I 691 
				第 18 
				
				ActiveX撞件
				//{{AFX一OOL_METHOO(CClockCtrl) 
				[id(2)) void Hello(); //}}AFX_OOL_METHOO 
				[id (0工 SPIO_ABOUTBOX) 1飞roid AboutBox ( ) ; 
				可以看到,在一DClock接口中所定义的每一个属性前面都有一个 id属性,其中括号内的数值就是该属性的调度白,也就是说,对 Interval这个属性来说,它的调度 B就是: 10 同时,可以看到接口中的方法也有一个调度 ID,例如上述例 18-18所示代码中 Hello方法的调度 B是 2。因此, BoundPropertyChanged函数就可以直接使用这些调度 E。于是,在 CClockCtrl类的 OnlntervalChanged函数中添加下面例 18-19所示代码中加灰显示的那条代码,通知容器: Clock控件中调度 B为 1的那个属性的值发生了改变。 
				i'll 18-19 
				
				void CClockCtrl : :OnlntervalChanged() 
				// TOOO : Add notificat工 on handler code if(m_interval6000) 
				m_ interval=1000 ; 
				else 
				m_ interval=m_interval/lOOO*1000; 
				Ki 11Timer (1) ; 
				SetTimer(l ,m_interval , NULL); 
				BoundPropertyChanged(Oxl) ; 
				
				SetMod工 f工 edFlag() ; 
				利用 Build命令生成最新的 Clock控件,然后回到 VB编程环境中,打开 VBTest测试工程,井打开 Clock控件的属性表单的 General属性页,这时,可以看到Interva1属性的值是 1000,将其修改为 2∞0,然后单击【应用】按钮,可以发现 Clock控件显示的时间变成每隔 2秒跳动一次了,同时可以看到 VB属性面板中 Interva1属性的值也变为 2ωo了,说明上面我们编写的通知代码生效了。这样,就不会再给用户造成迷惑了。 
				
				t性
							

相关资源