Serializing Different Versions of Persistent Data

The control writer knows which properties earlier versions of the control have and in what order they are serialized. Rather than ignoring the exchange object, the persistent custom properties of the old version of the control can be loaded or stored through the exchange object in a selective manner.

When an earlier version of persistent data is to be loaded, any new properties can be initialized to their default values.

Note   It is not recommended that new versions of a control remove features (such as properties) of earlier versions.

When an earlier version of persistent data is to be stored, any new properties can be skipped.

Consider a hypothetical version 2.0 of the Circle control that has a new custom property called BorderWidth. The BorderWidth property is of type short and has a default value of 1.

It is assumed that all versions of the Circle control will have all the properties of earlier versions, and that the properties are stored in the same order as in earlier versions. This is a recommendation for all  ActiveX controls.

Here is what the version 2.0 DoPropExchange function might look like:

void CCircCtrl::DoPropExchange(CPropExchange* pPX)
{
    ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor), FALSE);
    COleControl::DoPropExchange(pPX);
    PX_Bool(pPX, _T("CircleShape"), m_circleShape, TRUE);
    PX_Short(pPX, _T("CircleOffset"), m_circleOffset, 0);
    PX_Long(pPX, _T("FlashColor"), (long &)m_flashColor, RGB(0xFF,
        0x00, 0x00));
    PX_String(pPX, _T("Note"), m_note, _T(""));

    if (pPx->GetVersion() >= (DWORD)MAKELONG(_wVerMinor, _wVerMajor))
        PX_Short(pPX, _T("BorderWidth"), m_borderWidth, 1);
    else
        if (pPx->IsLoading())
          m_borderWidth = 1;
}

Notice the third parameter to the ExchangeVersion function. This is an optional parameter that specifies whether or not the control should store the same version of persistent data as was last loaded. By passing FALSE, the old version is maintained. The default for this parameter is TRUE, which specifies that the control should always store the current version of persistent data, no matter what version of persistent data is loaded.

All stock properties and custom properties from versions before 2.0 are serialized as usual, in the same order as they were in the earlier versions.

If the exchange object's version is greater than or equal to 2.0, the BorderWidth property is serialized as usual.

If the exchange object's version is less than 2.0, and the IsLoading function returns TRUE, the BorderWidth property is initialized to its default value.