Partage via


Optimisation de la persistance et de l'initialisation

Par défaut, la persistance et l'initialisation dans un contrôle sont gérées par la fonction membre DoPropExchange. Dans un contrôle classique, cette fonction contient des appels à plusieurs fonctions PX_ (PX_Color, PX_Fontet ainsi de suite), une pour chaque propriété.

L'avantage de cette approche est qu'une seule implémentation DoPropExchange peut être utilisée pour l'initialisation, pour la persistance au format binaire et pour la persistance au soi-disant format "conteneur de propriétés" utilisé par certains conteneurs. Cette unique fonction fournit toutes les informations sur les propriétés et leurs valeurs par défaut dans un emplacement pratique.

Toutefois, cette généralité se produit au détriment de l'efficacité. Les fonctions PX_ obtiennent leur flexibilité grâce à des implémentations multicouches qui sont intrinsèquement moins efficaces que plus directes, mais moins flexibles. En outre, si un contrôle passe une valeur par défaut à une fonction PX_ , cette valeur par défaut doit être fournie à chaque fois, même dans les situations où la valeur par défaut peut ne pas nécessairement être utilisée. Si la génération de la valeur par défaut est une tâche non triviale (par exemple, si la valeur est obtenue à partir d’une propriété ambiante), le travail supplémentaire non nécessaire est effectué dans les cas où la valeur par défaut n’est pas utilisée.

Vous pouvez améliorer les performances de persistance binaire de votre contrôle en remplaçant sa fonction Serialize. L'implémentation par défaut de cette fonction membre passe un appel à votre fonction DoPropExchange. En la remplaçant, vous pouvez fournir une implémentation plus directe pour la persistance binaire. Par exemple, observez la fonction DoPropExchange suivante :

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

Pour améliorer les performances de la persistance binaire de ce contrôle, vous pouvez remplacer la fonction Serialize comme suit :

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

La variable locale dwVersion peut être utilisée pour détecter la version de l'état persistant chargé ou enregistré du contrôle. Vous pouvez utiliser cette variable au lieu d’appeler CPropExchange ::GetVersion.

Pour économiser un peu d’espace dans le format persistant d’une propriété BOOL (et pour le maintenir compatible avec le format produit par PX_Bool), vous pouvez stocker la propriété en tant que BYTE, comme suit :

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

Notez que dans le cas de chargement, une variable temporaire est utilisée, puis sa valeur est affectée, au lieu de passer m_boolProp à une référence BYTE. La technique de cast n’entraînerait qu’un seul octet de m_boolProp en cours de modification, laissant les octets restants non initialisés.

Pour le même contrôle, vous pouvez optimiser l’initialisation du contrôle en remplaçant COleControl ::OnResetState comme suit :

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

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

Bien que les fonctions Serialize et OnResetState aient été substituées, la fonction DoPropExchange doit être conservée intacte, car elle est encore utilisée pour la persistance au format de conteneur de propriétés. Il est important de conserver ces trois fonctions pour garantir que le contrôle gère ses propriétés de manière cohérente, quel que soit le mécanisme de persistance utilisé par le conteneur.

Voir aussi

Contrôles ActiveX MFC : optimisation