本文讨论如何序列化 ActiveX 控件。 序列化是从永久性存储介质(如磁盘文件)读取或写入的过程。 Microsoft基础类 (MFC) 库为类 CObject中的序列化提供内置支持。 COleControl 通过使用属换机制将此支持扩展到 ActiveX 控件。
重要
ActiveX 是一项不推荐用于新开发的旧技术。 有关取代 ActiveX 的新式技术的详细信息,请参阅 ActiveX 控件。
通过重写 COleControl::DoPropExchange 来实现 ActiveX 控件的序列化。 此函数在加载和保存控件对象期间调用,存储使用成员变量或具有更改通知的成员变量实现的所有属性。
以下主题介绍了与序列化 ActiveX 控件相关的主要问题:
实现 DoPropExchange 函数
使用 ActiveX 控件向导生成控件项目时,会自动将多个默认处理程序函数添加到控件类,包括 COleControl::D oPropExchange 的默认实现。 以下示例显示了添加到使用 ActiveX 控件向导创建的类的代码:
void CMyAxUICtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
}
如果要使属性持久化,请通过添加对属性交换函数的调用来修改 DoPropExchange。 以下示例演示自定义布尔型 CircleShape 属性的序列化,其中 CircleShape 属性的默认值为 TRUE:
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, _T("CircleShape"), m_bCircleShape, TRUE);
}
下表列出了可用于序列化控件属性的可能属换函数:
| 属性交换函数 | 目的 |
|---|---|
| PX_Blob() | 序列化二进制大型对象 (BLOB) 数据类型属性。 |
| PX_Bool() | 序列化布尔类型属性。 |
| PX_Color() | 序列化一种类型的颜色属性。 |
| PX_Currency() | 序列化 CY(货币)类型属性。 |
| PX_Double() | 序列化 double 类型属性。 |
| PX_Font() | 序列化字体类型属性。 |
| PX_Float() | 序列化 float 类型属性。 |
| PX_IUnknown() | 序列化LPUNKNOWN类型的属性。 |
| PX_Long() | 序列化 long 类型属性。 |
| PX_Picture() | 序列化图片类型属性。 |
| PX_Short() | 序列化 short 类型属性。 |
| PXstring() | 序列化 CString 类型属性。 |
| PX_ULong() | 序列化 ULONG 类型属性。 |
| PX_UShort() | 序列化 USHORT 类型属性。 |
有关这些属换函数的详细信息,请参阅 MFC 参考中的 OLE 控件的持久性。
自定义 DoPropExchange 的默认行为
默认实现 DoPropertyExchange (如上一主题所示)调用基类 COleControl。 这将序列化由COleControl自动支持的属性集,这比仅序列化控件的自定义属性会使用更多的存储空间。 删除此调用后,对象只能序列化你认为重要的属性。 保存或加载控件对象时,控件已实现的任何库存属性状态都不会被序列化,除非对它们显式添加 PX_ 调用。
实现版本支持
版本支持使修改后的 ActiveX 控件能够添加新的持久性属性,并且仍能够检测和加载由早期版本的控件创建的持久状态。 若要使控件的版本作为其持久数据的一部分可用,请调用控件函数中的 DoPropExchange。 如果使用 ActiveX 控件向导创建 ActiveX 控件,则会自动插入此调用。 如果不需要版本支持,则可以将其删除。 不过,对于版本支持所提供的额外灵活性,控件大小的成本非常小(4 个字节)。
如果未使用 ActiveX 控件向导创建控件,需在 COleControl::ExchangeVersion 函数的开头插入以下行:首先,在调用 DoPropExchange 之前,添加对 COleControl::DoPropExchange 的调用。
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
}
可以使用任何 DWORD 作为版本号。 ActiveX 控件向导生成的项目默认使用 _wVerMinor 和 _wVerMajor。 这些是项目 ActiveX 控件类的实现文件中定义的全局常量。 在函数的 DoPropExchange 其余部分内,可以随时调用 CPropExchange::GetVersion 来检索要保存或检索的版本。
在以下示例中,此示例控件的版本 1 仅具有“ReleaseDate”属性。 版本 2 添加“OriginalDate”属性。 如果指示控件从旧版本加载永久性状态,则会将新属性的成员变量初始化为默认值。
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Long(pPX, _T("ReleaseDate"), m_ReleaseDate);
if (pPX->GetVersion() >= MAKELONG(0, 2))
{
PX_Long(pPX, _T("OriginalDate"), m_OriginalDate);
}
else
{
if (pPX->IsLoading())
m_OriginalDate = 0;
}
}
默认情况下,控件“将”旧数据转换为最新格式。 例如,如果控件的版本 2 加载版本 1 保存的数据,它将在再次保存时写入版本 2 格式。 如果希望控件以上次读取格式保存数据,请在调用时将 ExchangeVersion 作为第三个参数传递。 第三个参数是可选的,默认情况下为 TRUE 。