Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Improving ATL-ActiveX serialization

0.00/5 (No votes)
20 Jun 2003 1  
If an ActiveX container has to contain several Controls, serialization of controls may be made much faster with this technique.

Introduction

I have had to make an ActiveX container with the possibility to contain several controls (~100,200,600...). Apart from drawing considerations and optimizations, saving and loading times of controls may be a drawback when the number of them increase. And why? If you see the ATL code for the serialization of control's properties, you find the BEGIN_PROP_MAP() macro that defines, the properties of the controls that are serialized "one by one". At this point, is where resided my improvement.

Control properties serialization

See the following sample of ATL-Map with the properties of a control to serialize:

BEGIN_PROP_MAP(CMyControl
    PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
    PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
    PROP_DATA_ENTRY("value", m_nValue, VT_I4)
    PROP_DATA_ENTRY("mask", m_nMask, VT_I4)
    PROP_ENTRY("SafFile", DISPID_CTCSafFile, CLSID_NULL)
    ... etc.
END_PROP_MAP()

As you can see, properties' serialization are defined one by one. When the control is saved, this is translated to internal calls to IPersistStreamInit::Save(), and same when the control is loaded, with IPersistStreamInit::Load(). The key here is that, every PROP_DATA_ENTRY macro has an intrinsic call to IPersisteStreamInit::Load() or Save() (remember that an ATL-ActiveX control inherits and implements this interface by IPersistStreamInitImpl<> template).

If you have hundred of controls to save at the same time, and they have several properties saving or loading by one call to IPersistStreamInit interface per property, this may take several time. This can be improved by the following code:

BEGIN_PROP_MAP(CMyControl) 
    // (you left empty de properties map)

END_PROP_MAP() 
typedef struct CONTROLPROPERTIES
{
    // Define here the control properties

} CONTROLPROPERTIES;
CONTROLPROPERTIES m_properties;
// IPersistStreamInit 

public:
STDMETHOD(Load)( LPSTREAM pStm ) 
{ 
    if ( pStm == NULL ) return( E_POINTER );
    pStm->Read( &m_properties, sizeof(m_properties), NULL );
    return( S_OK );
}
STDMETHOD(Save)( LPSTREAM pStm, BOOL fClearDirty ) 
{
    if ( pStm == NULL ) return( E_POINTER );
    pStm->Write( &m_properties, sizeof(m_properties), NULL );
    if ( fClearDirty ) SetDirty(FALSE);
    return( S_OK );
}

With this way for saving and loading, every control is saved or loaded with an unique call to IPersistStreamInit::Save() or Load(), not one call per property, and so we can save time!!!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here