Optimieren von Persistenz und Initialisierung

Standardmäßig werden Persistenz und Initialisierung in einem Steuerelement von der DoPropExchange Memberfunktion behandelt. In einem typischen Steuerelement enthält diese Funktion Aufrufe mehrerer PX_ Funktionen (PX_Color, PX_Fontusw.), eine für jede Eigenschaft.

Dieser Ansatz hat den Vorteil, dass eine einzelne DoPropExchange Implementierung für die Initialisierung, für Persistenz im Binärformat und für Persistenz im sogenannten "Property-Bag"-Format verwendet werden kann, das von einigen Containern verwendet wird. Diese eine Funktion stellt alle Informationen zu den Eigenschaften und deren Standardwerten an einem praktischen Ort bereit.

Diese Generalität kommt jedoch auf Kosten der Effizienz. Die PX_ Funktionen erhalten ihre Flexibilität durch mehrschichtige Implementierungen, die inhärent weniger effizient sind als direkte, aber weniger flexible Ansätze. Wenn ein Steuerelement einen Standardwert an eine PX_ -Funktion übergibt, muss dieser Standardwert jedes Mal bereitgestellt werden, auch in Situationen, in denen der Standardwert möglicherweise nicht unbedingt verwendet wird. Wenn das Generieren des Standardwerts eine nichttrivielle Aufgabe ist (z. B. wenn der Wert aus einer Ambient-Eigenschaft abgerufen wird), wird zusätzliche, unnötige Arbeit in Fällen ausgeführt, in denen der Standardwert nicht verwendet wird.

Sie können die binäre Persistenzleistung Ihres Steuerelements verbessern, indem Sie die Funktion des Steuerelements Serialize überschreiben. Die Standardimplementierung dieser Memberfunktion ruft Ihre DoPropExchange Funktion auf. Durch Überschreiben können Sie eine direktere Implementierung für binäre Persistenz bereitstellen. Betrachten Sie z. B. diese DoPropExchange Funktion:

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(""));
}

Um die Leistung der binären Persistenz dieses Steuerelements zu verbessern, können Sie die Serialize Funktion wie folgt überschreiben:

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;
   }
}

Die dwVersion lokale Variable kann verwendet werden, um die Version des permanenten Zustands des Steuerelements zu erkennen, der geladen oder gespeichert wird. Sie können diese Variable anstelle des Aufrufs von CPropExchange::GetVersion verwenden.

Um im persistenten Format für eine BOOL-Eigenschaft etwas Platz zu sparen (und mit dem von PX_Boolihnen erstellten Format kompatibel zu halten), können Sie die Eigenschaft wie folgt als BYTE speichern:

if (ar.IsLoading())
{
   BYTE bTmp;
   ar >> bTmp;
   m_BoolProp = (BOOL)bTmp;
   // other properties...
}
else
{
   ar << (BYTE)m_BoolProp;
   // other properties...
}

Beachten Sie, dass im Ladefall eine temporäre Variable verwendet wird und ihr Wert zugewiesen wird, anstatt m_boolProp in einen BYTE-Verweis zu umwandeln. Die Umwandlungsmethode würde dazu führen, dass nur ein Byte von m_boolProp geändert wird, wodurch die neu initialisierte Byte nicht initialisiert werden Standard.

Für dasselbe Steuerelement können Sie die Initialisierung des Steuerelements optimieren, indem Sie COleControl::OnResetState wie folgt überschreiben:

void CMyAxOptCtrl::OnResetState()
{
   ResetVersion(MAKELONG(_wVerMinor, _wVerMajor));
   ResetStockProps();

   m_BoolProp = TRUE;
   m_ShortProp = 0;
   m_ColorProp = RGB(0xFF, 0x00, 0x00);
   m_StringProp.Empty();
}

Obwohl Serialize die Funktion überschrieben wurde und OnResetState überschrieben wurde, sollte die DoPropExchange Funktion erhalten bleiben, da sie weiterhin für persistenz im Eigenschaftenbehälterformat verwendet wird. Es ist wichtig, alle drei Funktionen zu Standard, um sicherzustellen, dass das Steuerelement seine Eigenschaften konsistent verwaltet, unabhängig davon, welcher Persistenzmechanismus der Container verwendet.

Siehe auch

MFC-ActiveX-Steuerelemente: Optimierung