次の方法で共有


永続化と初期化の最適化

既定では、コントロールの永続化と初期化は、 DoPropExchange メンバー関数によって処理されます。 一般的なコントロールでは、この関数には、プロパティごとに 1 つずつ、複数の PX_ 関数 (PX_ColorPX_Font など) の呼び出しが含まれています。

この方法には、初期化、バイナリ形式での永続化、一部のコンテナーで使用されるいわゆる "プロパティ バッグ" 形式での永続化に、1 つの DoPropExchange 実装を使用できるという利点があります。 この 1 つの関数は、プロパティとその既定値に関するすべての情報を 1 か所で提供します。

ただし、この一般化は効率を犠牲にしています。 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...
}

読み込み時には、BYTE 参照にm_boolPropをキャストするのではなく、一時変数が使用され、その値が割り当てられることに注意してください。 キャスト手法では、 m_boolPropの 1 バイトのみが変更され、残りのバイトは初期化されません。

同じコントロールの場合、 次のように 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関数はプロパティ バッグ形式での永続化に引き続き使用されるため、そのまま保持する必要があります。 コンテナーが使用する永続化メカニズムに関係なく、コントロールがそのプロパティを一貫して管理できるように、これらの 3 つの関数すべてを維持することが重要です。

こちらも参照ください

MFC ActiveX コントロール: 最適化