ATL Internals 2ed复习.chapter 7.COM Persistence

需要保存自身状态的object应该提供IPersistMedium,这里Medium=Stream,Storage,PropertyBag等

client决定何时在何种媒体上要保存object的状态,调用IPersistMedium的Load(),Save(),并且为这两个函数提供相应的IMedium接口

所有的IPersistMedium都派生自IPersist接口:

interface IPersist : IUnknown               
{ HRESULT GetClassID([out] CLSID* pclsid); }

object可以提供2种数据:

self-describing set,用户可读数据:例如txt,html,xml形式

opaque binary stream of bytes,流媒体数据:只有机器才能明白

 

IPropertyBag and IPersistPropertyBag

interface IPropertyBag : public IUnknown {                      
  HRESULT Read([in] LPCOLESTR pszPropName,                      
    [in, out] VARIANT* pVar, [in] IErrorLog* pErrorLog);        
                                                                
  HRESULT Write([in] LPCOLESTR pszPropName, [in] VARIANT* pVar);
};                                                              
                                                                
interface IPersistPropertyBag : public IPersist {               
  HRESULT InitNew ();                                           
  HRESULT Load([in] IPropertyBag* pPropBag,                     
    [in] IErrorLog* pErrorLog);                                 
  HRESULT Save([in] IPropertyBag* pPropBag,                     
    [in] BOOL fClearDirty,                                      
    [in] BOOL fSaveAllProperties);                              
};                                                              


 

IPropertyBag2 and IPersistPropertyBag2

interface IPropertyBag2 : public IUnknown {                     
  HRESULT Read([in] ULONG cProperties, [in] PROPBAG2* pPropBag, 
    [in] IErrorLog*  pErrLog, [out] VARIANT* pvarValue,          
    [out] HRESULT*   phrError);                                   
  HRESULT Write([in] ULONG cProperties, [in] PROPBAG2* pPropBag,
    [in] VARIANT*    pvarValue);                                   
  HRESULT CountProperties ([out] ULONG* pcProperties);          
  HRESULT GetPropertyInfo([in] ULONG iProperty,                 
    [in] ULONG cProperties,                                     
    [out] PROPBAG2* pPropBag, [out] ULONG* pcProperties);       
  HRESULT LoadObject([in] LPCOLESTR pstrName, [in] DWORD dwHint,
    [in] IUnknown* pUnkObject, [in] IErrorLog* pErrLog);        
};                                                              
                                                                
interface IPersistPropertyBag2 : public IPersist {              
  HRESULT InitNew ();                                           
  HRESULT Load ([in] IPropertyBag2* pPropBag,                   
    [in] IErrorLog* pErrLog);                                   
  HRESULT Save ([in] IPropertyBag2* pPropBag,                   
    [in] BOOL fClearDirty,                                      
    [in] BOOL fSaveAllProperties);                              
  HRESULT IsDirty();                                            
};                                                              

IPropertyBag2可以通过CountProperties()和GetPropertyInfo()了解Property的数量和类型

IPropertyBag2应该支持IPropertyBag的功能

IPersistPropertyBag2应该支持IPersistPropertyBag

The IStream, IpersistStreamInit, and IPersistStream Interfaces

ActiveX需要实现IpersistStreamInit或者IPersistStream

interface ISequentialStream : IUnknown {                        
    HRESULT Read([out] void *pv, [in] ULONG cb,                 
        [out] ULONG *pcbRead);                                  
                                                                
    HRESULT Write( [in] void const *pv, [in] ULONG cb,          
        [out] ULONG *pcbWritten);                               
                                                                
}                                                               
                                                                
interface IStream : ISequentialStream {                         
  HRESULT Seek([in] LARGE_INTEGER dlibMove,                     
               [in] DWORD dwOrigin,                             
               [out] ULARGE_INTEGER *plibNewPosition);          
  //...                                                         
}                                                               
                                                                
interface IPersistStreamInit : public IPersist {                
        HRESULT IsDirty();                                      
        HRESULT Load([in] LPSTREAM pStm);                       
        HRESULT Save([in] LPSTREAM pStm, [in] BOOL fClearDirty);
        HRESULT GetSizeMax([out] ULARGE_INTEGER*pCbSize);       
        HRESULT InitNew();                                      
};                                                              
                                                                
interface IPersistStream : public IPersist {                    
        HRESULT IsDirty();                                      
        HRESULT Load([in] LPSTREAM pStm);                       
        HRESULT Save([in] LPSTREAM pStm, [in] BOOL fClearDirty);
        HRESULT GetSizeMax([out] ULARGE_INTEGER*pCbSize);       
};                                                              


IPersistStreamInit和IPersistStream如果全部实现,例子:

class ATL_NO_VTABLE CDemagogue : public IPersistStreamInit, ... {
...
BEGIN_COM_MAP(CDemagogue)
  ...
  COM_INTERFACE_ENTRY(IPersistStreamInit)
  COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStreamInit)
  COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
END_COM_MAP()
...
};

IStorage and IPersistStorage

该接口用于OLE linking and embeding

interface IStorage : public IUnknown {                      
  HRESULT CreateStream([string,in] const OLECHAR* pwcsName, 
    [in] DWORD grfMode, [in] DWORD reserved1,               
    [in] DWORD reserved2,                                   
    [out] IStream** ppstm);                                 
                                                            
  HRESULT OpenStream([string,in] const OLECHAR* pwcsName,   
    [unique][in] void* reserved1, [in] DWORD grfMode,       
    [in] DWORD reserved2, [out] IStream** ppstm);           
                                                            
  HRESULT CreateStorage([string,in] const OLECHAR* pwcsName,
    [in] DWORD grfMode, [in] DWORD reserved1,               
    [in] DWORD reserved2,                                   
    [out] IStorage** ppstg);                                
                                                            
  HRESULT OpenStorage(                                      
    [string,unique,in] const OLECHAR* pwcsName,             
    [unique,in] IStorage* pstgPriority,                     
    [in] DWORD grfMode, [unique,in] SNB snbExclude,         
    [in] DWORD reserved, [out] IStorage** ppstg);           
                                                            
  // Following methods abbreviated for clarity...           
  HRESULT CopyTo( ... );                                    
  HRESULT MoveElementTo( ... )                              
  HRESULT Commit( ... )                                     
  HRESULT Revert(void);                                     
  HRESULT EnumElements( ... );                              
  HRESULT DestroyElement( . ., );    
  HRESULT RenameElement( ... );                             
  HRESULT SetElementTimes( ... );                           
  HRESULT SetClass( ... );                                  
  HRESULT SetStateBits( ... );                              
  HRESULT Stat( ... );                                      
};                                                          
                                                            
interface IPersistStorage : public IPersist {               
  HRESULT IsDirty ();                                       
  HRESULT InitNew ([unique,in] IStorage* pStg);             
  HRESULT Load ([unique,in] IStorage* pStg);                
  HRESULT Save ([unique,in] IStorage* pStgSave,             
    [in] BOOL fSameAsLoad);                                 
  HRESULT SaveCompleted ([unique,in] IStorage* pStgNew);    
  HRESULT HandsOffStorage ();                               
};                                                          


ATL实现的例子:

class ATL_NO_VTABLE CDemagogue :
    public IPersistPropertyBagImpl<CDemagogue>,
    public IPersistStreamInitImpl<CDemagogue>,
    public IPersistStorageImpl<CDemagogue> {
 ...
 BEGIN_COM_MAP(CDemagogue)
     ...
     COM_INTERFACE_ENTRY2(IPersist, IPersistPropertyBag)
     COM_INTERFACE_ENTRY(IPersistPropertyBag)
     COM_INTERFACE_ENTRY(IPersistStreamInit)
     COM_INTERFACE_ENTRY(IPersistStream)
     COM_INTERFACE_ENTRY(IPersistStorage)
 END_COM_MAP()
     ...
};


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值