Controles ActiveX MFC: serializando
Este artigo discute como serializar um controle ActiveX. Serialização é o processo de leitura ou gravação em um meio de armazenamento persistente, como um arquivo de disco. A biblioteca Microsoft Foundation Class (MFC) fornece suporte interno para serialização na classe CObject
. COleControl
estende esse suporte a controles ActiveX por meio do uso de um mecanismo de troca de propriedades.
Importante
O ActiveX é uma tecnologia herdada que não deve ser usada para novo desenvolvimento. Para mais informações sobre tecnologias modernas que substituem o ActiveX, confira Controles do ActiveX.
A serialização para controles ActiveX é implementada substituindo o COleControl::DoPropExchange. Essa função, chamada durante o carregamento e salvamento do objeto de controle, armazena todas as propriedades implementadas com uma variável de membro ou com uma variável de membro com notificação de alteração.
Os tópicos a seguir abordam os principais problemas relacionados à serialização de um controle ActiveX:
Implementar a função
DoPropExchange
para serializar seu objeto de controle
Implementar a função DoPropExchange
Quando você usa o Assistente de Controle ActiveX para gerar o projeto de controle, várias funções de manipulador padrão são adicionadas automaticamente à classe de controle, incluindo a implementação padrão de COleControl::DoPropExchange. O exemplo a seguir mostra o código adicionado às classes criadas com o Assistente de Controle ActiveX:
void CMyAxUICtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
}
Se você quiser tornar uma propriedade persistente, modifique DoPropExchange
adicionando uma chamada à função de troca de propriedades. O exemplo a seguir demonstra a serialização de uma propriedade CircleShape booliana personalizada, em que a propriedade CircleShape tem um valor padrão de TRUE:
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, _T("CircleShape"), m_bCircleShape, TRUE);
}
A tabela a seguir lista as possíveis funções de troca de propriedades que você pode usar para serializar as propriedades do controle:
Funções de troca de propriedades | Finalidade |
---|---|
PX_Blob( ) | Serializa uma propriedade de dados de tipo BLOB (objeto binário grande). |
PX_Bool( ) | Serializa uma propriedade de tipo booliana. |
PX_Color( ) | Serializa uma propriedade de tipo cor. |
PX_Currency( ) | Serializa uma propriedade de tipo CY (moeda). |
PX_Double( ) | Serializa uma propriedade de tipo double . |
PX_Font( ) | Serializa uma propriedade de tipo fonte. |
PX_Float( ) | Serializa uma propriedade de tipo float . |
PX_IUnknown( ) | Serializa uma propriedade de tipo LPUNKNOWN . |
PX_Long( ) | Serializa uma propriedade de tipo long . |
PX_Picture( ) | Serializa uma propriedade de tipo Imagem. |
PX_Short( ) | Serializa uma propriedade de tipo short . |
PXstring( ) | Serializa uma propriedade de tipo CString . |
PX_ULong( ) | Serializa uma propriedade de tipo ULONG. |
PX_UShort( ) | Serializa uma propriedade de tipo USHORT. |
Para obter mais informações sobre essas funções de troca de propriedades, consulte Persistência de Controles OLE na Referência do MFC.
Personalizar o comportamento padrão do DoPropExchange
A implementação padrão de DoPropertyExchange
(conforme mostrado no tópico anterior) faz uma chamada para a classe base COleControl
. Isso serializa automaticamente o conjunto de propriedades com suporte de COleControl
, que usa mais espaço de armazenamento do que serializar apenas as propriedades personalizadas do controle. A remoção dessa chamada permite que seu objeto serialize apenas as propriedades que você considera importantes. Qualquer propriedade de estoque afirma que o controle implementado não será serializado ao salvar ou carregar o objeto de controle, a menos que você adicione explicitamente chamadas PX_ para eles.
Implementar o suporte de versão
O suporte de versão permite que um controle ActiveX revisado adicione novas propriedades persistentes e ainda seja capaz de detectar e carregar o estado persistente criado por uma versão anterior do controle. Para disponibilizar a versão de um controle como parte de seus dados persistentes, chame COleControl::ExchangeVersion na função DoPropExchange
do controle. Essa chamada será inserida automaticamente se o controle ActiveX tiver sido criado usando o Assistente de Controle ActiveX. Ela poderá ser removida se o suporte de versão não for necessário. No entanto, o custo no tamanho do controle é muito pequeno (4 bytes) para a flexibilidade adicional que o suporte de versão fornece.
Se o controle não foi criado com o Assistente de Controle ActiveX, adicione uma chamada a COleControl::ExchangeVersion
inserindo a linha a seguir no início da função DoPropExchange
(antes da chamada para COleControl::DoPropExchange
):
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
}
Você pode usar qualquer DWORD como o número de versão. Projetos gerados pelo Assistente de Controle ActiveX usam _wVerMinor
e _wVerMajor
como padrão. Essas são constantes globais definidas no arquivo de implementação da classe de controle ActiveX do projeto. No restante da função DoPropExchange
, você pode chamar CPropExchange::GetVersion a qualquer momento para recuperar a versão que você está salvando ou recuperando.
No exemplo a seguir, a versão 1 deste controle de exemplo tem apenas uma propriedade "ReleaseDate". A versão 2 adiciona uma propriedade "OriginalDate". Se o controle for instruído a carregar o estado persistente da versão antiga, ele inicializará a variável de membro da nova propriedade com um valor padrão.
void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Long(pPX, _T("ReleaseDate"), m_ReleaseDate);
if (pPX->GetVersion() >= MAKELONG(0, 2))
{
PX_Long(pPX, _T("OriginalDate"), m_OriginalDate);
}
else
{
if (pPX->IsLoading())
m_OriginalDate = 0;
}
}
Por padrão, um controle "converte" dados antigos no formato mais recente. Por exemplo, se a versão 2 de um controle carregar dados que foram salvos pela versão 1, ele gravará o formato da versão 2 quando for salvo novamente. Se você quiser que o controle salve dados no formato lido pela última vez, passe FALSE como um terceiro parâmetro ao chamar ExchangeVersion
. Esse terceiro parâmetro é opcional e é TRUE por padrão.