Оптимизация постоянства и инициализации
По умолчанию сохраняемость и инициализация в элементе управления обрабатываются DoPropExchange
функцией-членом. В типичном элементе управления эта функция содержит вызовы нескольких функций PX_ (PX_Color
и PX_Font
т. д.), по одному для каждого свойства.
Этот подход имеет преимущество, что единая DoPropExchange
реализация может использоваться для инициализации, сохраняемости в двоичном формате и сохраняемости в так называемом формате property-bag, используемом некоторыми контейнерами. Эта одна функция предоставляет все сведения о свойствах и их значениях по умолчанию в одном удобном месте.
Тем не менее, эта обобщенность приходит за счет эффективности. Функции 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();
}
Хотя Serialize
и OnResetState
были переопределены, функция должна оставаться нетронутой, DoPropExchange
так как она по-прежнему используется для сохранения в формате контейнера свойств. Важно поддерживать все три этих функции, чтобы элемент управления последовательно управлял своими свойствами независимо от того, какой механизм сохраняемости использует контейнер.