Examples
The following is some code in Visual Basic that illustrates the usage of the SFL property bag implementations.
Initializing and loading an object from an XML property bag
Set bag = New XMLPropertyBag
bag.Init "books.xml"
bag.Load "BooksCollection", Books
bag.Commit
Saving an existing object to a registry property bag
Set bag = New RegistryPropertyBag
bag.Init "Software\Stingray\SFL\Persistence"
bag.Save "BooksCollection", Books
bag.Commit
The implementation of the persistable object in Visual Basic requires the class to be marked as Persistable, by assigning the corresponding value to the class properties. This adds two methods to the class, ReadProperties() and WriteProperties(), which correspond to the Load() and Save() methods of the IPropertyBag interface. Implementing Load() and Save() methods for a collection class shows the implementation of these methods for a book collection class.
Implementing Load() and Save() methods for a collection class
Private Sub Class_ReadProperties(PropBag As PropertyBag)
Dim count As Integer
count = PropBag.ReadProperty("BooksCount")
ReDim Books(1 To count)
Dim i As Integer
For i = 1 To count
Set Books(i) = PropBag.ReadProperty("Book" & i)
Next i
End Sub
Private Sub Class_WriteProperties(PropBag As PropertyBag)
Dim count As Integer
count = UBound(Books)
PropBag.WriteProperty "BooksCount", count
Dim i As Integer
For i = 1 To count
PropBag.WriteProperty "Book" & i, Books(i)
Next i
End Sub
To implement a persistable object in C++, you need to implement one of the COM interfaces IPersistPropertyBag or IPersistPropertyBag2. How to do this depends on the framework you are using to develop your components. Implementing a persistable C++ object using ATL shows what it might look like if you used ATL.
Implementing a persistable C++ object using ATL
class CPersistableComponent:
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CPersistableComponent, &__uuidof(CPersistableComponent)>,
public IMyComponent,
public IPersistPropertyBag
{
public:
BEGIN_COM_MAP(CPersistableComponent)
COM_INTERFACE_ENTRY(IPersistPropertyBag)
COM_INTERFACE_ENTRY2(IPersist, IPersistPropertyBag)
COM_INTERFACE_ENTRY(IMyComponent)
END_COM_MAP()
º
};
It is important to notice that persistable COM objects need to be creatable, since the property bag needs to create a new instance using the standard COM mechanisms whenever it is retrieving an object of that class. To be created, an object requires a CLSID and a registered class factory.
Implementing Save() and Load() methods for a persistable C++ object shows the implementation of the Save() and Load() methods of a persistable object. The implementation makes use of the Load() and Save() methods in the IPropertyBag (or IPropertyBag2) interface pointer it receives as a parameter to retrieve or store individual pieces of data the object considers to be part of its persistent internal state.
Implementing Save() and Load() methods for a persistable C++ object
STDMETHOD(Load)(IPropertyBag* pPropBag, IErrorLog* pErrorLog)
{
HRESULT hr = S_OK;
_variant_t vaProp;
hr = pPropBag->Read(OLESTR("Number"), &vaProp, pErrorLog);
if (FAILED(hr)) return E_FAIL;
m_nANumber = static_cast<long>(vaProp);
vaProp.Clear();
CPoint pt;
hr = pPropBag->Read(OLESTR("PositionX"), &vaProp, pErrorLog);
if (FAILED(hr)) return E_FAIL;
pt.x = static_cast<long>(vaProp);
hr = pPropBag->Read(OLESTR("PositionY"), &vaProp, pErrorLog);
if (FAILED(hr)) return E_FAIL;
pt.y = static_cast<long>(vaProp);
return S_OK;
}
STDMETHOD(Save)(IPropertyBag* pPropBag, BOOL fClearDirty,
BOOL fSaveAllProperties)
{
HRESULT hr = S_OK;
_variant_t vaProp;
vaProp = static_cast<long>(m_nANumber);
hr = pPropBag->Write(OLESTR("Number"), &vaProp);
if (FAILED(hr)) return E_FAIL;
vaProp = static_cast<long>(m_rc.left);
hr = pPropBag->Write(OLESTR("PositionX"), &vaProp);
if (FAILED(hr)) return E_FAIL;
vaProp = static_cast<long>(m_rc.top);
hr = pPropBag->Write(OLESTR("PositionY"), &vaProp);
if (FAILED(hr)) return E_FAIL;
return S_OK;
}






