PRB: COleControl::Serialize Not Called with VB as Container
ID: Q141274
|
The information in this article applies to:
-
Microsoft Visual Basic Standard and Professional Editions for Windows, version 4.0
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 2.2, 4.0
-
Microsoft OLE Control Developer's Kit (CDK)
SYMPTOMS
Although OLE controls are used with certain control containers (such as
Microsoft Visual Basic version 4.0), the Serialize function for the control-
derived class is not called. These containers allow the control to store
its persistent information either by using the property sets or by using
the IPersistPropertyBag interface. Both these methods call
COleControl::DoPropExchange directly without calling the control's
Serialize function.
The resolution section of this article discusses a technique that you can
use in the DoPropExchange method to store CObject-derived objects.
CAUSE
COleControl::Serialize is called by the framework when an OLE control
container uses one of the following persistent storage interfaces for
loading and saving the control: IPersistStorage, IPersistStreamInit, or
IPersistMemory.
If a control container uses any other method to store the control's
persistent information, then Serialize for the control-derived class will
not be called. Microsoft Visual Basic, for example, uses either
IPersistPropertyBag or property sets to store the persistent information
for an OLE control; therefore, the Serialize function for a control is not
called when Visual Basic is used as the control container.
RESOLUTION
Although there is no direct support for serializing CObject-derived objects
in COleControl::DoPropExchange, you might want to use the following
technique to store objects in an OLE control:
- Allocate a block of memory with GlobalAlloc.
// cbGuess is a guess of how much memory will be needed.
// If more is needed, CSharedFile will reallocate.
HGLOBAL hMem = GlobalAlloc(GPTR, cbGuess);
BYTE *pbMem = (BYTE *)hMem;
- Construct an instance of CSharedFile and attach it to the memory block,
starting four bytes in. Because the CSharedFile class is not yet
documented, include afxpriv.h:
CSharedFile file;
file.Attach(pMem + sizeof(DWORD), cbGuess - sizeof(DWORD));
- Construct an instance of CArchive on the file:
CArchive ar(&file, CArchive::store);
- Write the CObject-derived objects into the archive:
// store data in the archive
// for example, if m_myObject is a CObject-derived object, then
m_myObject.Serialize(ar);
- Get the length of the file and write it into the first DWORD of the
memory block:
*(DWORD*)pbMem = file.GetLength();
- Pass the memory block to PX_Blob:
PX_Blob(pPX, _T("MyObjects"), hMem);
This code could be used for loading the objects back out of the blob. For
more information about how to use PX_Blob to serialize/de-serialize data,
Please see the following article in the Microsoft Knowledge Base:
Q137333 DOCERR: How to Use the PX_Blob Function
To get optimal performance in IPersistStreamInit, ensure that the OLE
control maintains a separate Serialize method that writes the CObjects
directly to its archive. Care should be taken to save all of the control's
persistent data in both Serialize and DoPropExchange.
STATUS
This behavior is by design.
MORE INFORMATION
An OLE control generated using ControlWizard can read and write its
persistent state using one of the following interfaces: IPersistMemory,
IPersistStorage, IPersistStreamInit, IPersistPropertyBag (not
implemented in versions before Visual C++ 4.x), and IDataObject through the
property sets implementation. Each of these interfaces with the exception
of IPersistPropertyBag and IDataObject call COleControl::Serialize passing
in a CArchive. This archive could be used to store CObject-derived objects
as part of the control's persistence.
Some OLE control containers (like Microsoft Visual Basic) use the "save as
text" mechanism in order to allow as much of the OLE control's state to be
represented in a human-readable format. For optimizing this mechanism, the
interfaces IPropertyBag and IPersistPropertyBag are used and therefore are
recommended for containers like Visual Basic. IPropertyBag is implemented
by the container and is roughly analogous to IStream. IPersistPropertyBag
is implemented by controls and is roughly analogous to
IPersistStream(Init).
Visual Basic uses the control's IPersistPropertyBag interface, if one is
implemented by the control, or it uses the property sets. Property sets are
communicated from and to the control through IDataObject::GetData and
IDataObject::SetData, implemented by the control. Note that OLE controls
generated using earlier versions of Visual C++ don't provide an
implementation for IPersistPropertyBag.
The implementation provided by the MFC framework for IPersistPropertyBag
and property sets directly call COleControl::DoPropExchange passing in an
instance of either CPropbagPropExchange or CPropsetPropExchange
respectively.
REFERENCES
OLE Controls Inside Out - by Adam Denning
Additional query words:
2.00 2.10 2.20 3.00 3.10 3.20 4.00
Keywords : kbole kbCtrl kbMFC kbVC
Version : 4.00 2.00 2.10 2.20
Platform : NT WINDOWS
Issue type :