MFC ActiveX 控件:序列化

本文讨论如何序列化 ActiveX 控件。 序列化是从永久性存储介质(如磁盘文件)读取或写入的过程。 Microsoft基础类 (MFC) 库为类 CObject中的序列化提供内置支持。 COleControl 通过使用属换机制将此支持扩展到 ActiveX 控件。

重要

ActiveX 是一项不推荐用于新开发的旧技术。 有关取代 ActiveX 的新式技术的详细信息,请参阅 ActiveX 控件

通过重写 COleControl::D oPropExchange 来实现 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 (currency) 属性。
PX_Double() 序列化类型 double 属性。
PX_Font() 序列化 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 控件能够添加新的持久性属性,并且仍能够检测和加载由早期版本的控件创建的持久状态。 若要使控件的版本作为其持久数据的一部分可用,请调用控件函数中的 DoPropExchangeCOleControl::ExchangeVersion。 如果使用 ActiveX 控件向导创建 ActiveX 控件,则会自动插入此调用。 如果不需要版本支持,则可以将其删除。 但是,控制大小的成本非常小(4 字节),以增加版本支持提供的灵活性。

如果未使用 ActiveX 控件向导创建控件,请在函数开头DoPropExchange插入以下行(在调用之前):添加对控件的调用:COleControl::ExchangeVersionCOleControl::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时将 FALSE 作为第三个参数传递。 第三个参数是可选的,默认情况下为 TRUE

另请参阅

MFC ActiveX 控件