共用方式為


最佳化持續性和初始化

根據預設,控制項中的持續性和初始化是由成員函式處理 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();
}

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

另請參閱

MFC ActiveX 控制項:最佳化