MORE INFORMATION
Typically, the container application presents the user with a dialog
box containing the various types of objects that can be created on a
particular system. These object types are enumerated from the
Registration Database--each entry in the database has a name that the
user can understand, as well as a unique identifier for the object
type called a CLSID.
The container tells OLE that it wants to create an object. At this
point, the container gives OLE the CLSID of the desired object, a
pointer to a child storage within the container's compound file, and a
pointer variable for OLE to return a pointer to a requested interface
(typically IOleObject):
Container OLE
----------- -----------
|OleCreate|--->| |
| | | |
| | | |
| | | |
| | | |
| | | |
----------- -----------
The OLE libraries then consult the registration database to find the
name of the executable file associated with the CLSID:
Container OLE
----------- -----------
|OleCreate|--->| |
| | | |
| | | |
| | | |
| | | |
| | | |
----------- -----------
|
V
Reg DB
The server is then started with the -Embedding flag. When the server
parses the command line and sees the -Embedding flag, it knows that it
is being started on behalf of OLE and should remain hidden until it is
explicitly told to become visible. At this point, the server registers
a pointer to its IClassFactory interface with OLE:
Container OLE Server
----------- ----------- -----------------
|OleCreate|--->| |--->| |
| | | |<---| IClassFactory |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
----------- ----------- -----------------
|
V
Reg DB
OLE calls the server through the IClassFactory interface and asks to
instantiate an object, returning the pointer to the interface
requested by the container in the creation routine:
Container OLE Server
----------- ----------- ------------------
|OleCreate|--->| |--->| |
| | | |<---| IClassFactory |
| | | |--->| ------------- |
| | | |<---|-|IOleObject | |
| | | | | |IDataObject| |
| | | | | | etc | |
| | | | | ------------- |
----------- ----------- ------------------
|
V
Reg DB
OLE queries the object for the IDataObject interface, and then calls
GetData method to fill the presentation cache with a metafile,
device-independent bitmap (DIB), or a bitmap. Later, when the
container asks the object to draw itself, OLE will intercept the call
and use one of the entries in the presentation cache:
Container OLE Server
----------- ----------- ------------------
|OleCreate|--->| |--->| |
| | | |<---| IClassFactory |
| | | |--->| ------------- |
| | | |<---|-|IOleObject | |
| | | | | |IDataObject| |
| | | | | | etc | |
| | | | | ------------- |
----------- ----------- ------------------
| |
V v
Reg DB Cache
At this point, the creation routine returns to the container. Now, the
container will generally query the interface pointer returned for the
IViewObject interface. The container uses the IViewObject interface to
ask the object to notify the container (through the container's
IAdviseSink interface) every time the object's view changes, so that
the container can update its display. At this point, the server
creates an advise holder to notify the object of its changes:
Container OLE Server
-------------- ------------- ------------------
| | | | | |
| | | | | IClassFactory |
| | | | | ------------- |
| |--->|IOleObject |----->|IOleObject | |
| | | | | |IDataObject| |
| | | | | | etc | |
| | | | | ------------- |
|IAdviseSink |<---| |<---|IOleAdviseHolder|
-------------- ------------- ------------------
| |
V v
Reg DB Cache
NOTE: The object still is not visible at this point. Now an explicit
call to IOleObject::DoVerb() must be made with the verb OLEIVERB_SHOW.
This tells the server to make the object visible for editing.
Every time the user makes a change to the object, the object calls OLE
through the advise holder to notify the libraries that the view has
been changed. The libraries then query the object for the new
presentation(s) to fill the presentation cache. Then the advise sink
of the container application is called to notify the container that
its view is no longer up to date, and should be repainted.
The container then in turn tells OLE to draw the object, at which
point the libraries render the information from the cache.
At some point, the user tells the server that he or she is finished
editing the object. The server tells the container that it is now
going away, and that the object needs to be saved into the container's
persistent storage. The container responds by telling the object to
save itself into a substorage of the container's compound file. The
OLE libraries "intercept" this call and save internal state
information, as well as the presentation cache, into streams of this
substorage. Then, the libraries tell the object to save itself into
the container provided substorage.
After saving the object, the container's compound file resembles the
following:
----------------
| Root Storage |
----------------
| --------------- * = Stream
|---| object | - = Storage
| | sub-storage |
| ---------------
| | ****************
| |---* OLE State *
| | ****************
| | ****************
| |---* Presentation *
| | ****************
| | ****************
| |---* Native Data *
| ****************
| ***************
| * Container *
|--- * State *
* Information *
***************
The container can continue to redraw the object even though the server
application is no longer around because the object's presentation is
stored in OLE's internal cache:
Container OLE
-------------- -------------
| | | |
| | | |
| | | |
| |--->|IOleObject |
| | | |
| | | |
| | | |
|IAdviseSink |<---| |
-------------- -------------
| |
V v
Reg DB Cache
Now the user can save the document in the container application and
exit. Upon exiting, the container queries the object for the
IViewObject interface so the container can tell OLE to stop sending
updates. Then the container asks the object to close.
If the user now reloads the document, or moves the document to another
machine, the OLE libraries can still render the object because the
presentation is actually stored within the container's compound file.
When the object is reloaded, the libraries can refill the presentation
cache from the information stored within the compound file.