Support for Scripting
Any time you run the ATL Simple Object Wizard and choose Dual as the interface type, ATL generates an interface definition for the default interface that derives from
IDispatch
and is
<object classid="clsid:859512CF-E4D8-450C-AF09-6578FE2F6DC2"
id=objPiCalculator>
</object>
<script language=vbscript>
' Set the digits property
objPiCalculator.digits = 5
' Calculate pi
dim pi
pi = objPiCalculator.CalcPi
' Tell the world!
document.write "Pi to " &
objPiCalculator.digits
& _
" digits is " & pi
</script>
For more information about how to handle the inconvenient data types associated with scriptingnamely, BSTR s and VARIANT ssee Chapter 2, "Text and Strings," and Chapter 3, "ATL Smart Types." |
Adding PersistenceATL 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
[
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." |