Adding
Persistence
ATL
provides base classes for objects that want to be persistentthat
is, saved to some persistence medium (such as a disk) and restored
later. COM objects expose this support by implementing one of the
COM persistence interfaces, such as IPersistStreamInit,
IPersistStorage, or IPersistPropertyBag. ATL
provides implementation of these three persistence
interfacesnamely, IPersistStreamInitImpl,
IPersistStorageImpl, and IPersistPropertyBagImpl.
Your COM object supports persistence by deriving from any of these
base classes, adding the interface to your COM_MAP, and
adding a data member called m_bRequiresSave that each of
these base classes expects.
class ATL_NO_VTABLE CCalcPi :
public ICalcPi,
public IAdvertiseMyself,
public IPersistPropertyBagImpl<CCalcPi> {
public:
...
// ICalcPi
public:
STDMETHOD(CalcPi)(/*[out, retval]*/ BSTR* pbstrPi);
STDMETHOD(get_Digits)(/*[out, retval]*/ long *pVal);
STDMETHOD(put_Digits)(/*[in]*/ long newVal);
public:
BOOL m_bRequiresSave; // Used by persistence base classes
private:
long m_nDigits;
};
However, that's not quite all there is to it.
ATL's implementation of persistence needs to know which parts of
your object need to be saved and restored. For that information,
ATL's implementations of the persistent interfaces rely on a table
of object properties that you want to persist between sessions.
This table, called a PROP_MAP, contains a mapping of
property names and dispatch identifiers (as defined in the IDL
file). So, given the following interface:
[
object,
...
]
interface ICalcPi : IDispatch {
[propget, id(1)] HRESULT Digits([out, retval] LONG* pVal);
[propput, id(1)] HRESULT Digits([in] LONG newVal);
};
the PROP_MAP would be contained inside
our implementation of ICalcPi like this:
class ATL_NO_VTABLE CCalcPi : ...
{
...
public:
BEGIN_PROP_MAP(CCalcPi)
PROP_ENTRY("Digits", 1, CLSID_NULL)
END_PROP_MAP()
};
Given an implementation
of IPersistPropertyBag, our IE sample code can be expanded
to support initialization of object properties via persistence
using the <param> tag:
<object classid="clsid:E5F91723-E7AD-4596-AC90-17586D400BF7"
id=objPiCalculator>
<param name=digits value=5>
</object>
<script language=vbscript>
' Calculate pi
dim pi
pi = objPiCalculator.CalcPi
' Tell the world!
document.write "Pi to " & objPiCalculator.digits &_
" digits is " & pi
</script>
For more information about ATL's implementation
of persistence, see Chapter 7, "Persistence in ATL."
|