本文讨论序列化 ActiveX 控件的方法。序列化是从持久性存储媒体(如磁盘文件)中读取或向其中写入的进程。Microsoft 基础类 (MFC) 库在 CObject 类中为序列化提供内置支持。COleControl 通过使用属性交换机制,将此支持扩展到 ActiveX 控件。
通过重写 COleControl::DoPropExchange 实现 ActiveX 控件的序列化。在加载和保存控件对象期间调用此函数,以存储用成员变量或用带更改通知的成员变量实现的所有属性。用户可以对控件进行序列化以记录控件的状态。
下列主题介绍与序列化 ActiveX 控件相关的主要问题:
实现 <code>DoPropExchange</code>函数以序列化控件对象
<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_activex_controls.3a_.serializing.asp?frame=true#_core_customizing_the_default_%20_of_dopropexchange">自定义序列化过程</a>
<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_activex_controls.3a_.serializing.asp?frame=true#_core_implementing_version_support">实现版本支持</a>
当使用“ActiveX 控件向导”生成控件项目时,几个默认处理函数被自动添加到控件类,包括 COleControl::DoPropExchange 的默认实现。下例显示添加到用“ActiveX 控件向导”创建的类的代码:
如果要使属性持久,则通过添加对属性交换函数的调用来修改 <code>DoPropExchange</code>。下例说明自定义布尔 CircleShape 属性的序列化,这里 CircleShape 属性的默认值为 TRUE:
下表列出了可用于序列化控件属性的可能的属性交换函数:
属性交换函数
目的
PX_Blob( )
序列化二进制大对象 (BLOB) 类型数据属性。
PX_Bool( )
序列化布尔类型属性。
PX_Color( )
序列化颜色类型属性。
PX_Currency( )
序列化 CY(货币)类型属性。
PX_Double( )
序列化 double 类型属性。
PX_Font( )
序列化 Font 类型属性。
PX_Float( )
序列化 float 类型属性。
PX_IUnknown( )
序列化 LPUNKNOWN 类型属性。
PX_Long( )
序列化 long 类型属性。
PX_Picture( )
序列化 Picture 类型属性。
PX_Short( )
序列化 short 类型属性。
PX_String( )
序列化 CString 类型属性。
PX_ULong( )
序列化 ULONG 类型属性。
PX_UShort( )
序列化 USHORT 类型属性。
有关这些属性交换函数的更多信息,请参见“MFC 参考”中的 OLE 控件的持久性。
DoPropertyExchange 的默认实现(如上一主题所示)调用 COleControl 基类。此操作序列化 COleControl 自动支持的属性集,所使用的存储空间比只序列化控件的自定义属性多。移除此调用使您的对象得以只序列化您认为重要的那些属性。保存或加载控件对象时,除非对控件已实现的任何常用属性状态显式添加 PX_ 调用,否则将不会序列化它们。
版本支持使修订过的 ActiveX 控件得以添加新的持久性属性,并仍可以检测和加载由早期版本的控件创建的持久性状态。若要使控件的版本可用作其持久性数据的一部分,请在控件的 <code>DoPropExchange</code> 函数中调用 COleControl::ExchangeVersion。如果 ActiveX 控件是用“ActiveX 控件向导”创建的,则将自动插入此调用。如果不需要版本支持,可移除此调用。但是,控件大小的成本对于版本支持所提供的额外灵活性非常小(4 个字节)。
如果控件不是用“ActiveX 控件向导”创建的,则通过在 <code>DoPropExchange</code> 函数的开始处(在调用 COleControl::DoPropExchange 之前)插入下行来添加对 COleControl::ExchangeVersion 的调用:
可以使用任何 DWORD 作为版本号。“ActiveX 控件向导”所生成的项目使用 _wVerMinor 和 _wVerMajor 作为默认值。_wVerMinor 和 _wVerMajor 是在项目的 ActiveX 控件类的实现文件中定义的全局常数。在 <code>DoPropExchange</code> 函数的其余部分,可以随时调用 CPropExchange::GetVersion 检索正在保存或检索的版本。
在下例中,此示例控件的版本 1 仅有“ReleaseDate”属性。版本 2 添加了“OriginalDate”属性。如果指示控件从旧版本加载持久性状态,则控件将新属性的成员变量初始化为默认值。
默认情况下,控件将旧数据“转换”成最新格式。例如,如果控件的版本 2 加载由版本 1 保存的数据,则数据再次保存时将写成版本 2 的格式。如果希望控件以上次读取的格式保存数据,则在调用 ExchangeVersion 时将 FALSE 作为第三个参数传递。此第三个参数是可选的,默认值为 TRUE。
另:属性页交换函数
属性页上的控件变量与ActiveX控件的属性建立联系使用DDP_ 函数。
如:DDP_Text(pDX,IDC_CODE,m_code,_T("CodeString")); 是将m_code与属性CodeString建立联系。
常用属性页交换函数:
函 数 名
函数的作用
DDP_CBIndex
链接组合框中选定字符串的索引与控件属性
DDP_CBString
链接组合框中的选定字符串与控件属性。所选字符串可以以与属性值相同的字母开始,但不必完全与其匹配
DDP_CBStringExact
链接组合框中的选定字符串与控件属性。所选字符串和属性的字符串值必须完全匹配
DDP_Check
链接复选框与控件属性
DDP_LBIndex
链接列表框中选定字符串的索引与控件属性
DDP_LBString
链接列表框中的选定字符串与控件属性。所选字符串可以以与属性值相同的字母开始,但不必完全与其匹配
DDP_LBStringExact
链接列表框中的选定字符串与控件属性。所选字符串和属性的字符串值必须完全匹配
DDP_Radio
链接单选按钮与控件属性
DDP_Text