/*此文是我将网上的一些文章,自已遇到的问题进行整理,有些是翻译,所有只供学习讨论,如有版权还属于原作者——作者:黄森堂*/
#25 如何持续化参数属性?
在正常状态下支持二进制与文本的持续化,控件分别需要实现IPersistStreamInit与IPersistPropertyBag接口,ATL提供了该接口的包装类IPersistStreamInitImpl与IPersistPropertyBagImpl,在装入与存储属性中,这两个类分别调用了CComControlBase::IPersistStreamInit_Load()/Save()与CComControlBase::IPersistPropertyBag_Load()/Save() ,且调用CComDispatchDriver::GetProperty(),在这里面又调用了invoke()来指定特殊的属性值,然后CComDispatchDriver::GetProperty()只实现支持单个属性值,签于此点,ATL 2.1的属性持续化机制不支持索引属性。
要突破这个限制,得在你的控件中覆盖持续化路径,并依照标准来实现文本与二进制的持续化,作为替代,你的属性应象这样定义:
[propget, id(4), helpstring("Indexed Property")] HRESULT ParamProp(
[in] short nIndex, [out, retval] short *pVal);
[propput, id(4), helpstring("Indexed Property ")] HRESULT ParamProp(
[in] short nIndex, [in] short newVal);
为了支持IPersistStreamInit,你需要覆盖CComControlBase::IPersistStreamInit_Save():
HRESULT IPersistStreamInit_Save(LPSTREAM pStm,
BOOL fClearDirty ,
ATL_PROPMAP_ENTRY* pMap
)
{
if(!pStm)
{
return E_POINTER;
}
for(UINT nIndex = 0; nIndex < 12; nIndex++)
{
if(FAILED(pStm->Write(&(m_nColor[nIndex]),
sizeof(m_nColor[nIndex]), NULL))
{
return E_UNEXPECTED;
}
}
//调用默认的基类来实现存储单属性值PROP_MAP
return CComControlBase::IPersistStreamInit_Save(pStm, fClearDirty, pMap);
}
如果你要实现IPersistPropertyBag接口,你得覆盖了Load()与Save()方法.