最佳化持續性和初始化
根據預設,控制項中的持續性和初始化是由成員函式處理 DoPropExchange
。 在一般控制項中,此函式包含對數 個PX_ 函式的呼叫,每個 PX_Color
PX_Font
屬性各一個。
這種方法的優點是,單 DoPropExchange
一實作可用於初始化、二進位格式的持續性,以及某些容器所使用的所謂「屬性包」格式的持續性。 此一個函式會在一個方便的地方提供屬性及其預設值的所有資訊。
然而,這種普遍性是以效率為代價。 PX_ 函式會透過多層式實作取得彈性,這些實作原本就比直接、但較不具彈性的實作更有效率。 此外,如果控制項將預設值傳遞至 PX_ 函式,則每次都必須提供該預設值,即使在可能不一定使用預設值的情況下也一樣。 如果產生預設值是非Trivial 工作(例如,從環境屬性取得該值時),則在未使用預設值的情況下,就會執行額外的不必要的工作。
您可以覆寫控制項的 Serialize
函式來改善控制項的二進位持續性效能。 此成員函式的預設實作會呼叫您的 DoPropExchange
函式。 藉由覆寫它,您可以為二進位持續性提供更直接的實作。 例如,請考慮此 DoPropExchange
函式:
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(""));
}
若要改善此控制項二進位持續性的效能,您可以覆寫 函 Serialize
式,如下所示:
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;
}
}
局部 dwVersion
變數可用來偵測載入或儲存控制項持續狀態的版本。 您可以使用此變數,而不是呼叫 CPropExchange::GetVersion 。
若要在 BOOL 屬性的永續性格式 中節省一些空間(並讓它與 所產生的 PX_Bool
格式相容),您可以將屬性儲存為 BYTE ,如下所示:
if (ar.IsLoading())
{
BYTE bTmp;
ar >> bTmp;
m_BoolProp = (BOOL)bTmp;
// other properties...
}
else
{
ar << (BYTE)m_BoolProp;
// other properties...
}
請注意,在載入案例中,會使用暫存變數,然後指派其值,而不是將m_boolProp 轉換成 BYTE 參考。 轉換技術只會造成修改m_boolProp 的 一個位元組,讓其餘的位元組未初始化。
針對相同的控制項,您可以覆寫 COleControl::OnResetState 來優化控制項的初始化,如下所示:
void CMyAxOptCtrl::OnResetState()
{
ResetVersion(MAKELONG(_wVerMinor, _wVerMajor));
ResetStockProps();
m_BoolProp = TRUE;
m_ShortProp = 0;
m_ColorProp = RGB(0xFF, 0x00, 0x00);
m_StringProp.Empty();
}
雖然 Serialize
和 OnResetState
已被覆寫,但函式應該保持不變, DoPropExchange
因為它仍然用於屬性包格式的持續性。 請務必維護這三個函式,以確保控制項會一致地管理其屬性,而不論容器所使用的持續性機制為何。