共用方式為


優化持續性和初始化

根據預設,控件中的持續性和初始化是由成員函式處理 DoPropExchange 。 在一般控制元件中,此函式包含對數個PX_函式的呼叫,每個屬性都有一個呼叫,例如PX_ColorPX_Font等。

這種方法的優點是,單 DoPropExchange 一實作可用於初始化、二進位格式的持續性,以及某些容器所使用的所謂「屬性包」格式的持續性。 此一個函式會在一個方便的地方提供屬性及其預設值的所有資訊。

然而,這種普遍性是以效率為代價。 PX_函式透過多層次的實作來獲得彈性,這些實作天生比直接但較不具彈性的方式沒有效率。 此外,如果控件將預設值傳遞至 PX_ 函式,則每次都必須提供該預設值,即使在可能不一定使用預設值的情況下也一樣。 如果要產生預設值是一項不簡單的工作(例如,當該值是從環境屬性取得時),那麼在未使用預設值的情況下就會執行額外的、不必要的工作。

您可以覆寫控件的 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();
}

雖然 SerializeOnResetState 已被覆寫,但 DoPropExchange 函數應保持完整,因為它仍然用於屬性包格式的持續性。 請務必維護這三個函式,以確保控件會一致地管理其屬性,而不論容器所使用的持續性機制為何。

另請參閱

MFC ActiveX 控件:優化