Microsoft Foundation Classes                           Microsoft Corporation
Technical Notes 

#8 : General OLE Overview

This note gives a general overview of OLE, and the OLE support provided
by the MFC library.

The first section is an extract from the OLE API documentation.
The second section describes how the MFC OLE classes provide an
interface to the system level OLE libraries.

=============================================================================
General OLE Overview
====================

Compound Documents 
------------------

An application that uses OLE can cooperate with other OLE applications to
produce a document containing different kinds of data, all of which can be
easily manipulated by the user. The user editing such a document is able to
improve the document by using the best features of many different
applications. An application that implements OLE allows its users
to move away from an application-centered view of computing and toward a
document-centered view.

A document that supports OLE objects can contain many kinds of
data in many different formats; such a document is called a compound
document. A compound document uses the facilities of different OLE
applications to manipulate the different kinds of data it displays. Any kind
of data format can be incorporated into a compound document; with little or
no extra code.  The user working with a compound document does not need
to know which data formats are compatible with one another or how to find
and start any applications that created the data. Whenever a user chooses to
work with part of a compound document, the application responsible for that
part of the document starts automatically.

Linked and Embedded Objects
---------------------------

An object is any data that can be presented in a compound document and
manipulated by a user. Anything from a single cell in a spreadsheet to an
entire document can be an object. When an object is incorporated into a
document, it maintains an association with the application that produced it.

For example, if a range of spreadsheet cells were an embedded object in a
text file, all the data associated with the cells would be saved as part of
the text file, including any necessary formulas.
The name of the server for the spreadsheet cells would be saved along with
this data. The user could select this embedded object while working with the
text file, and the spreadsheet application would be started automatically
for editing those cells.
If the range of cells were a linked object instead of an embedded object,
the data would be stored in some other file and only a link to the data
would be saved with the text file. The presentation of the data and the
behavior of the cells would be the same as for an embedded object.

Verbs
-----

The types of actions a user can perform on an object are called verbs. Two
typical verbs for an object are 'Play' and 'Edit'.

The nature of an object determines its behavior when a user works with it.
The most typical use for some objects, such as voice annotations and
animated scripts, is to play them. For example, a user could play an
animated script by double clicking it. In this case, 'Play' is the primary
verb for the object.

For other objects, the most typical use is to edit them. In the case of text
produced by a word processor, for example, the primary verb could be 'Edit'.

The client application typically specifies the primary verb when the user
double-clicks an object. However, the server application determines the
meaning of that verb. A user can invoke an object's subsidiary verbs by
using the class name Object menu item or the Links dialog box.

Many objects support only one verb - for example, an object created by a
text editor might support only 'Edit'. If an object supports only one verb,
that verb is used no matter what the client application specifies.

Benefits of Object Linking and Embedding
----------------------------------------

OLE offers the following benefits:

  An application can specialize in performing one job very well. For
   example, a drawing application that implements OLE would not necessarily
   need any text-editing tools; a user could put text into the drawing and
   edit that text by using any text editor that supports OLE.

  An application automatically extensible for future data formats, because
   the content of an object does not matter to the containing document.

  A user can concentrate on the task instead of on any applications
   required to complete the task.

  A File can be more compact, because linking to objects allows a file to
   use an object without having to store that object's data.

  A document can be printed or transmitted without using the application
   that originally produced the document.

  Linked objects in a file can be updated dynamically.

-----------------------------------------------------------------------------
Data Transfer in OLE
---------------------

This section gives a brief overview of how applications share information
under OLE.

Client Applications
-------------------

An OLE client application can accept, display, and store OLE objects. The
objects themselves can contain any kind of data. A client application
typically identifies an object with a distinctive border or other visual
cue.

Server Applications
-------------------

An OLE server is any application that can edit or otherwise manipulate an
object in response to a request from a client application.
When the user double-clicks an object in a client application, the
server associated with that object starts and the user works with the object
inside the server application. When the server starts, its window is
typically sized so that only the object is visible. If the user
double-clicks a linked object, the entire linked file is loaded, and the
linked portion of the file is selected. For embedded objects, the user
chooses the Update command from the File menu to save changes to the object
and chooses Exit when finished.

Many applications are capable of acting as both clients and servers for
OLE objects.

Clipboard Conventions
---------------------

When first embedding or linking an object, OLE client and server
applications typically exchange data by using the clipboard. When a server
application puts an object on the clipboard, it represents the object with
data formats, such as Native data, OwnerLink data, ObjectLink data, and a
presentation format. The order in which these formats are put on the
clipboard is very important, because the order determines the type of
object. For example, if the first format is Native and the second is
OwnerLink, client applications can use the data to create an embedded
object. If the first format is ObjectLink, however, the data describes a
linked object.

Native data completely defines an object for a particular server. The data
can be meaningful only to the server application. The client application
provides storage for Native data, in the case of embedded objects.

Presentation formats allow the client library to display the object in a
document. CF_METAFILEPICT, CF_DIB, and CF_BITMAP are typical presentation
formats.

MFC OLE supports Native and CF_METAFILEPICT data formats.  Additional
formats can be added.

Registration
------------

The system registration database supports OLE by providing a system-wide
source of information about whether server applications support the OLE
protocol, the names of the executable files for these applications,
the verbs for classes of objects, and whether an object-handler library
exists for a given class of object.

When a server application is installed, it registers itself as an OLE
server with the system registration database. (This database is
supported by the dynamic-link library SHELL.DLL.) To register itself
as an OLE server, a setup program, or the AfxOleRegisterServerName()
function records in the database information detailing what OLE
protocols are supported.

For example, the MFC sample ole server MINSVR in
\C700\MFC\SAMPLES\MINSVR can be registered just by running the
application in a standalone mode.  Standalone means running the
application from the main menu, file manager, or by clicking an icon.

If the location of the server changes, then just re-run the server
application to change the database information.  However, if you are
currently running a client program (i.e. TestClnt, OClient, Word For
Windows, etc.) while re-registering the server, the client must be
shut down and restarted to recieve the updated location.

When a client activates a linked or embedded object, the client library
finds the command line for the server in the database, appends the
"/Embedding" or "/Embedding <filename>" command-line option, and uses the new
command line to start the server. (Starting the server with either of these
options differs from the user starting it directly. Either a slash (/) or a
hyphen (-) can precede the word "Embedding.)

Registration Database
---------------------

Applications typically add key/value pairs to the registration database by
using the Microsoft Windows Registration Editor. (For more information about
this application, see Microsoft Windows Programming Tools.) Applications
could also use the registration functions to add this information to the
database.

To be available for OLE transactions, a server should register the key/value
pairs as illustrated below: (see TN010.TXT for more details)

HKEY_CLASSES_ROOT\.ext = class name
HKEY_CLASSES_ROOT\class name = readable version of class name
HKEY_CLASSES_ROOT\class name\protocol\StdFileEditing\server =
        executable file name
HKEY_CLASSES_ROOT\class name\protocol\StdFileEditing\handler =
        dll name
HKEY_CLASSES_ROOT\class name\protocol\StdFileEditing\verb\0 =
        primary verb
HKEY_CLASSES_ROOT\class name\protocol\StdFileEditing\verb\1 =
        secondary verb

For compatibility with earlier applications, the system registration service
also reads and writes registration information in the [embedding] section of
the WIN.INI initialization file.

The protocol "StdFileEditing" is currently the only OLE protocol used
for linking and embedding.

=============================================================================
=============================================================================
MFC and OLE
===========

Applications use three dynamic-libraries, OLECLI.DLL, OLESVR.DLL, and
SHELL.DLL, to implement object linking and embedding. Object linking and
embedding is supported by OLECLI.DLL and OLESVR.DLL. The system registration
database is supported by SHELL.DLL.

The MFC library support for OLE makes some simplifying assumptions to make
the common OLE services easier to implement.

For those familiar with the existing C based OLE API, please read the next
section which describes the differences between MFC OLE and the system
OLE interface.


MFC OLE v.s. OLE API
--------------------
Here are the basic differences between MFC OLE and the system OLE API.

Language:
        MFC OLE:        C++
        OLE API:        C

Library Interface:
        MFC OLE:        C++ classes
        OLE API:        Handles, and manually built jump tables (_VTBLs)

Server requests:
        MFC OLE:        Synchronous
        OLE API:        Mostly synchronous, but may be asynchronous
        (i.e. MFC OLE automatically handles OLE_WAIT_FOR_RELEASE)

Special case handling for errors, retry:
        MFC OLE:        Provided by library
        OLE API:        Your program must do it all

Return codes:
        MFC OLE:        As with standard MFC/Windows API, return useful 
                          values, with Exceptions thrown if appropriate.
        OLE API:        Return OLESTATUS all the time.

User Interface Support:
        MFC OLE:        Support for "Insert New Object" dialog, "Links"
                        dialog and support for the "Object" menu item
                        attached to the "Edit" menu.
        OLE API:        none.

Other notes:
    * MFC OLE does not currently support "Object Handlers" (i.e. DLLs that
        are more efficient than launching a server application)
    * MFC OLE assumes there is one OLECLIENT for each OLEOBJECT (this is
        part of the OLE API design, but wasn't reflected in old source
        code examples).
    * Users of MFC OLE do not need to build manual VTBLs or call
        MakeProcInstance as described by the OLE API (the MFC libraries
        do all that low level binding for you).
    * MFC OLE does not currently support the "Paste Special" dialog.

    * MFC OLE does not provide C++ interfaces to all of the OLE API
        functions, just the most useful ones.
    * MFC OLE is built on top of the OLE API and DLLs. It is easy to
        call additional OLE APIs or use the underlying OLE API if needed.
    * Since MFC OLE is built on top of the OLE API, the underlying transport
        mechanism is the same as all other OLE Apps (i.e. DDE is still
        the communication standard).  MFC OLE apps work with any other
        OLE apps.

-----------------------------------------------------------------------------
MFC OLE Classes
---------------

MFC OLE splits the OLE API functionality into two disjoint sets of classes,
one set for client programs, the other set for server programs.
If a program wants to be both a client and a server, it will use all
the OLE classes.  The interface to all MFC OLE classes are contained
in the one C++ header file "afxole.h" that includes the standard OLE API
C header file "ole.h".

Terminology note: MFC OLE uses the term "item" to indicate an OLE object
that supports the "StdFileEditing" protocol (to avoid confusion with
the C++ and MFC term "object").

General classes:
    COleException is a general exception class used by both
        Clients and Servers.  See MFC overview and class
        reference documentation for more information on exceptions.

The Client classes include:
    COleClientDoc is a client document that manages client items
    COleClientItem is the client-side connection to an embedded or
        linked OLE item.

The Server classes include:
    COleServer is a server application that creates and manages server
        documents.
    COleServerDoc is a server document that creates and manages server items
    COleServerItem is the server-side of an embedded or linked OLE item.

Notes:
    * All MFC OLE classes start with 'COle'.
    * With the exception of COleException, you must derive your own classes
    from each of these COle classes in order to build a working application.

See TN009.TXT for what you must do to build a client app.
See TN010.TXT for what you must do to build a server app.

-----------------------------------------------------------------------------

A class hierarchy diagram of the MFC OLE classes shows the relationship
    between the library classes any your derived classes:

    CObject
       COleClientDoc
           << your client doc >>
       COleClientItem
            << your client item >>
       COleServer
            << your server app >>
       COleServerDoc
            << your server doc >>
       COleServerItem
            << your server item >>
       CException
            COleException


A more interesting diagram shows the relationships between MFC OLE objects:

        CLIENT APPLICATION            SERVER APPLICATION

    client application                           COleServer
        \                                        /
        COleClientDoc                         COleServerDoc
           \                                /
            COleClientItem    < ----- > COleServerItem

    To recap:
        * a client application can have zero or more COleClientDocs
        * each COleClientDoc can have zero or more COleClientItems
        * a COleServer can have zero or more COleServerDocs
        * each COleServerDoc can have zero or more COleServerItems

-----------------------------------------------------------------------------
Notes on using the MFC OLE Classes
----------------------------------
Important Note: The connection between 'COleClientItem' and
'COleServerItem' in the above diagram is for illustrative purposes only.
The actual connection is through a DDE link which is established and
managed by the OLE DLLs.  A client application should never directly
call a member function of a OLE Server class (COleServer, COleServerDoc
or COleServerItem).  Similarly a server application should never
directly call a member function of an OLE client class (COleClientDoc
or COleClientItem).

Many of the member functions in the MFC OLE classes are 'protected',
and some are even pure virtual.
You are responsible for implementing these overridable callbacks even
though you will rarely if ever call them directly.

=============================================================================
