Otimizando persistência e inicialização
Por padrão, a persistência e a inicialização em um controle são tratadas pela função membro DoPropExchange
. Em um controle típico, essa função contém chamadas para várias funções PX_ (PX_Color
, PX_Font
e assim por diante), uma para cada propriedade.
Essa abordagem tem a vantagem de que uma só implementação de DoPropExchange
pode ser usada para inicialização, para persistência no formato binário e para persistência no chamado formato "property-bag" usado por alguns contêineres. Essa função fornece todas as informações sobre as propriedades e seus valores padrão em um local conveniente.
No entanto, essa generalidade vem em detrimento da eficiência. As funções PX_ obtêm flexibilidade por meio de implementações multicamadas que são inerentemente menos eficientes do que abordagens mais diretas, mas menos flexíveis. Além disso, se um controle passar um valor padrão para uma função PX_, esse valor padrão deverá ser fornecido sempre, mesmo em situações em que não possa necessariamente ser usado. Se gerar o valor padrão for uma tarefa não trivial (por exemplo, quando o valor é obtido de uma propriedade ambiente), trabalho extra e desnecessário será feito nos casos em que o valor padrão não for usado.
Você pode aprimorar o desempenho de persistência binária do controle substituindo a função Serialize
do controle. A implementação padrão dessa função membro faz uma chamada para sua função DoPropExchange
. Ao substituí-la, você pode fornecer uma implementação mais direta para persistência binária. Por exemplo, considere esta função 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(""));
}
Para aprimorar o desempenho da persistência binária desse controle, você pode substituir a função Serialize
da seguinte maneira:
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;
}
}
A variável dwVersion
local pode ser usada para detectar a versão do estado persistente do controle sendo carregada ou salva. Você pode usar essa variável em vez de chamar CPropExchange::GetVersion.
Para economizar algum espaço no formato persistente para uma propriedade BOOL (e mantê-la compatível com o formato produzido por PX_Bool
), você pode armazenar a propriedade como um BYTE, da seguinte maneira:
if (ar.IsLoading())
{
BYTE bTmp;
ar >> bTmp;
m_BoolProp = (BOOL)bTmp;
// other properties...
}
else
{
ar << (BYTE)m_BoolProp;
// other properties...
}
Observe que, no caso de carga, uma variável temporária é usada e, em seguida, seu valor é atribuído, em vez de converter m_boolProp em uma referência de BYTE . A técnica de conversão resultaria na modificação de apenas um byte de m_boolProp, deixando os bytes restantes não inicializados.
Para o mesmo controle, você pode otimizar a inicialização do controle substituindo COleControl::OnResetState da seguinte maneira:
void CMyAxOptCtrl::OnResetState()
{
ResetVersion(MAKELONG(_wVerMinor, _wVerMajor));
ResetStockProps();
m_BoolProp = TRUE;
m_ShortProp = 0;
m_ColorProp = RGB(0xFF, 0x00, 0x00);
m_StringProp.Empty();
}
Embora Serialize
e OnResetState
tenham sido substituídas, a função DoPropExchange
deve ser mantida intacta porque ainda é usada para persistência no formato property-bag. É importante manter todas essas três funções para garantir que o controle gerencie suas propriedades de modo consistente, independentemente do mecanismo de persistência usado pelo contêiner.