现在的位置: 首页 > 综合 > 正文

MFC ActiveX 控件:序列化(msdn)和属性页

2012年07月30日 ⁄ 综合 ⁄ 共 3308字 ⁄ 字号 评论关闭

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

通过重写 COleControl::DoPropExchange 实现 ActiveX 控件的序列化。在加载和保存控件对象期间调用此函数,以存储用成员变量或用带更改通知的成员变量实现的所有属性。用户可以对控件进行序列化以记录控件的状态。

下列主题介绍与序列化 ActiveX 控件相关的主要问题:

实现 DoPropExchange 函数

当使用“ActiveX 控件向导”生成控件项目时,几个默认处理函数被自动添加到控件类,包括 COleControl::DoPropExchange 的默认实现。下例显示添加到用“ActiveX 控件向导”创建的类的代码:

void CSampleCtrl::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 CSampleCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, "CircleShape", m_bCircleShape, TRUE);
}
PX_Bool(pPX, "CircleShape", m_bCircleShape, TRUE);
第一个参数:指向CPropExchange类型变量的指针
第二个参数:属性名称
第三个参数:相应的成员变量
第四个参数:默认值,可选参数。

下表列出了可用于序列化控件属性的可能的属性交换函数:

属性交换函数 目的
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 控件的持久性。

自定义 DoPropExchange 的默认行为

DoPropertyExchange 的默认实现(如上一主题所示)调用 COleControl 基类。此操作序列化 COleControl 自动支持的属性集,所使用的存储空间比只序列化控件的自定义属性多。移除此调用使您的对象得以只序列化您认为重要的那些属性。保存或加载控件对象时,除非对控件已实现的任何常用属性状态显式添加 PX_ 调用,否则将不会序列化它们。

实现版本支持

版本支持使修订过的 ActiveX 控件得以添加新的持久性属性,并仍可以检测和加载由早期版本的控件创建的持久性状态。若要使控件的版本可用作其持久性数据的一部分,请在控件的 DoPropExchange 函数中调用 COleControl::ExchangeVersion。如果 ActiveX 控件是用“ActiveX 控件向导”创建的,则将自动插入此调用。如果不需要版本支持,可移除此调用。但是,控件大小的成本对于版本支持所提供的额外灵活性非常小(4 个字节)。

如果控件不是用“ActiveX 控件向导”创建的,则通过在 DoPropExchange 函数的开始处(在调用 COleControl::DoPropExchange 之前)插入下行来添加对 COleControl::ExchangeVersion 的调用:

void CSampleCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
...
}

可以使用任何 DWORD 作为版本号。“ActiveX 控件向导”所生成的项目使用 _wVerMinor_wVerMajor 作为默认值。_wVerMinor_wVerMajor 是在项目的 ActiveX 控件类的实现文件中定义的全局常数。在 DoPropExchange 函数的其余部分,可以随时调用 CPropExchange::GetVersion 检索正在保存或检索的版本。

在下例中,此示例控件的版本 1 仅有“ReleaseDate”属性。版本 2 添加了“OriginalDate”属性。如果指示控件从旧版本加载持久性状态,则控件将新属性的成员变量初始化为默认值。

void CSampleCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Long(pPX, "ReleaseDate", m_releaseDate);
if (pPX->GetVersion() >= MAKELONG(0, 2))
{
PX_Long(pPX, "OriginalDate", m_originalDate);
}
else
{
if (pPX->IsLoading())
m_originalDate = 0;
}
}

默认情况下,控件将旧数据“转换”成最新格式。例如,如果控件的版本 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

抱歉!评论已关闭.