Ottimizzazione di persistenza e inizializzazione
Per impostazione predefinita, la persistenza e l'inizializzazione in un controllo vengono gestite dalla DoPropExchange
funzione membro. In un controllo tipico questa funzione contiene chiamate a diverse funzioni PX_ (PX_Color
, PX_Font
e così via), una per ogni proprietà.
Questo approccio offre il vantaggio che una singola DoPropExchange
implementazione può essere usata per l'inizializzazione, per la persistenza in formato binario e per la persistenza nel formato cosiddetto "property-bag" usato da alcuni contenitori. Questa funzione fornisce tutte le informazioni sulle proprietà e i relativi valori predefiniti in un'unica posizione comoda.
Tuttavia, questa generalità è a scapito dell'efficienza. Le funzioni PX_ ottengono la loro flessibilità tramite implementazioni multilivello che sono intrinsecamente meno efficienti rispetto ad approcci più diretti, ma meno flessibili. Inoltre, se un controllo passa un valore predefinito a una funzione PX_ , tale valore predefinito deve essere fornito ogni volta, anche in situazioni in cui il valore predefinito potrebbe non essere necessariamente utilizzato. Se la generazione del valore predefinito è un'attività nontriva (ad esempio, quando il valore viene ottenuto da una proprietà di ambiente), vengono eseguite operazioni aggiuntive e non necessarie nei casi in cui il valore predefinito non viene usato.
È possibile migliorare le prestazioni di persistenza binaria del controllo eseguendo l'override della funzione del Serialize
controllo. L'implementazione predefinita di questa funzione membro effettua una chiamata alla DoPropExchange
funzione. Eseguendo l'override, è possibile fornire un'implementazione più diretta per la persistenza binaria. Si consideri ad esempio questa DoPropExchange
funzione:
void CMyAxOptCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, _T("BoolProp"), m_BoolProp, TRUE);
PX_Short(pPX, _T("ShortProp"), m_ShortProp, 0);
PX_Color(pPX, _T("ColorProp"), m_ColorProp, RGB(0xFF, 0x00, 0x00));
PX_String(pPX, _T("StringProp"), m_StringProp, _T(""));
}
Per migliorare le prestazioni della persistenza binaria di questo controllo, è possibile eseguire l'override della Serialize
funzione come indicato di seguito:
void CMyAxOptCtrl::Serialize(CArchive& ar)
{
SerializeVersion(ar, MAKELONG(_wVerMinor, _wVerMajor));
SerializeExtent(ar);
SerializeStockProps(ar);
if (ar.IsLoading())
{
ar >> m_BoolProp;
ar >> m_ShortProp;
ar >> m_ColorProp;
ar >> m_StringProp;
}
else
{
ar << m_BoolProp;
ar << m_ShortProp;
ar << m_ColorProp;
ar << m_StringProp;
}
}
La dwVersion
variabile locale può essere usata per rilevare la versione dello stato permanente del controllo caricato o salvato. È possibile usare questa variabile anziché chiamare CPropExchange::GetVersion.
Per risparmiare poco spazio nel formato permanente per una proprietà BOOL (e per mantenerlo compatibile con il formato prodotto da PX_Bool
), è possibile archiviare la proprietà come BYTE, come indicato di seguito:
if (ar.IsLoading())
{
BYTE bTmp;
ar >> bTmp;
m_BoolProp = (BOOL)bTmp;
// other properties...
}
else
{
ar << (BYTE)m_BoolProp;
// other properties...
}
Si noti che nel caso di caricamento viene usata una variabile temporanea e quindi viene assegnato il relativo valore, anziché eseguire il cast m_boolProp a un riferimento BYTE. La tecnica di cast comporterà la modifica di un solo byte di m_boolProp , lasciando i byte rimanenti non inizializzati.
Per lo stesso controllo, è possibile ottimizzare l'inizializzazione del controllo eseguendo l'override di COleControl::OnResetState come indicato di seguito:
void CMyAxOptCtrl::OnResetState()
{
ResetVersion(MAKELONG(_wVerMinor, _wVerMajor));
ResetStockProps();
m_BoolProp = TRUE;
m_ShortProp = 0;
m_ColorProp = RGB(0xFF, 0x00, 0x00);
m_StringProp.Empty();
}
Anche se Serialize
e OnResetState
sono stati sottoposti a override, la DoPropExchange
funzione deve essere mantenuta intatta perché viene ancora usata per la persistenza nel formato contenitore delle proprietà. È importante mantenere tutte e tre queste funzioni per garantire che il controllo gestisca le relative proprietà in modo coerente, indipendentemente dal meccanismo di persistenza usato dal contenitore.