MFC TN008--General OLE Overview

Created: April 15, 1992

ABSTRACT

This technical note gives a general overview of object linking and embedding (OLE) and the OLE support that the MFC library provides.

The Microsoft Foundation Class (MFC) library provides a full-featured set of C++ object classes for the MicrosoftÒ WindowsÔ graphical environment. It includes classes that directly support application development for Windows as well as general-purpose classes for collections, files, persistent storage, exceptions, diagnostics, memory management, strings, and time. Each MFC technical note describes a feature of MFC using code fragments and examples.

COMPOUND DOCUMENTS

An application that uses object linking and embedding (OLE) can cooperate with other applications that use OLE to produce a document that contains different types of data, all of which the user can easily manipulate. The user can enhance the document by incorporating data produced with many applications. Users of an application that implements OLE can move from an application-centered view of computing to a document-centered view.

A document that supports OLE objects can contain many kinds of data in different formats and is called a compound document. A compound document uses the facilities of different OLE applications to manipulate different types of data. Any data format can be incorporated into a compound document, with little or no extra code. The user need not know which data formats are compatible or how to find and start an application that created the data. When a user works 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 present in a compound document and that the user can manipulate. 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 is embedded in a text file, all data associated with the cells, including formulas, is saved as part of the text file. The name of the server for the spreadsheet cells is also saved. If the user selects this embedded object while working with the text file, the spreadsheet application starts automatically.

If the range of cells is a linked object instead of an embedded object, the data is stored in another file, and only a link to the data is saved with the text file. The presentation of the data and the behavior of the cells are the same as that of 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 how it behaves 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.

The most typical use of other objects is to edit them. The primary verb for text produced by a word processor is 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 Object menu item or the Links dialog box.

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

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 can act 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 in the Clipboard, it represents the object with data formats, such as Native data, OwnerLink data, or ObjectLink data, and a presentation format. The order in which these formats are put in the Clipboard determines the object type. 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 and is meaningful only to the server application. The client application stores Native data for 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 systemwide 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. (The SHELL.DLL dynamic link library supports this database.) To register itself as an OLE server, a setup program or the AfxOleRegisterServerName function records the database information, detailing which OLE protocols are supported.

For example, you can register the MFC sample OLE server MINSVR in \C700\MFC\SAMPLES\MINSVR by simply running the application in a stand-alone mode, that is, from the Program Manager, from the File Manager, or by clicking an icon.

If the location of the server changes, rerun the server application to change the database information. However, if you are currently running a client program (for example, TestClnt, OClient, Word for Windows), you must shut down and restart the client application so that it receives the updated location.

When a client activates a linked or an 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 is different 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. Applications can 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 (for details, see “Writing an MFC OLE Server Application,” TN010):

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.

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

MFC AND OLE

Applications use three dynamic link 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.

Readers familiar with the existing C-based OLE application programming interface (API) should review the next section, which describes the differences between MFC OLE and the system OLE interface.

MFC OLE vs. 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 (that is, MFC OLE automatically handles OLE_WAIT_FOR_RELEASE)

Special case handling for errors and retry:

MFC OLE: Provided by library

OLE API: Your program must do it all

Return codes:

MFC OLE: Like rest of Windows, 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 box and Links dialog box; support for the Object menu item attached to the Edit menu

OLE API: None

Other notes:

MFC OLE does not currently support object handlers (that is, DLLs that are more efficient than launching a server application).

MFC OLE assumes 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 automatically all do low-level binding for you).

MFC OLE does not currently support the Paste Special dialog box.

MFC OLE does not provide C++ interfaces to all the OLE API functions, only to 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.

Because MFC OLE is built on top of the OLE API, its underlying transport mechanism is the same as all other OLE applications—that is, dynamic data exchange (DDE) is still the communication standard. MFC OLE applications work with any other OLE applications.

MFC OLE Classes

MFC OLE splits the OLE API functionality into two disjoint sets of classes, one for client programs and one for server programs. If a program wants to be both a client and a server, it uses all the OLE classes. The interface to all MFC OLE classes is contained in the C++ header file AFXOLE.H that includes the standard OLE API C header file OLE.H.

To avoid confusion with the C++ and MFC term object, MFC OLE uses the term item to indicate an OLE object that supports the StdFileEditing protocol.

General classes:

COleException is a general exception class that both clients and servers use.

Client classes:

COleClientDoc is a client document that manages client items.

COleClientItem is the client-side connection to an embedded or linked OLE item.

Server classes:

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.

Note:

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

For information on building a client application, see “Writing an MFC OLE Client Application” (TN009).

For information on building a server application, see “Writing an MFC OLE Server Application” (TN010).

Figure 1 is a class hierarchy diagram of the MFC OLE classes showing the relationship between the library classes and your derived classes.

Figure 1.

Figure 2 is a more interesting diagram that shows the relationships between MFC OLE objects.

Figure 2.

To summarize:

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.

Using the MFC OLE Classes

The connection between COleClientItem and COleServerItem in Figure 2 is for illustrative purposes only. The actual connection is through a DDE link that the OLE DLLs establish and manage. A client application should never directly call a member function of an 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 although you will rarely, if ever, call them directly.