Programming Guide: OpenDoc Extension Interface

# Programming Guide

## OpenDoc Extension Interface

You can greatly extend the capabilities of your parts, in terms of fast processing of information or communication with other parts, if you use the interface-extension capabilities of OpenDoc. The extension protocol allows parts or other OpenDoc objects to increase their capabilities by extending their programming interfaces. By using extension interfaces, your parts can communicate with other parts or other kinds of OpenDoc components in ways not possible with the standard OpenDoc programming interface.

You design, create, and attach such an extension to your part editor. At run-time, other parts can then access and use the extension interface, through calls to your part.

### Extension Objects

All subclasses of ODObject, including shapes, facets, documents, windows, frames, and parts, can be extended. An extension is itself an object, an instantiation of a subclass of ODExtension. Each extension object is related to its base object by its extension name. A base object is the object whose interface it extends. The extension name is an ISO type name. A caller accesses a base object's extension through that extension name. This base object has nothing to do with inheritance.

Extensible objects create and delete their own extensions and manage the extensions' storage. If desired, a base object can share an extension object among multiple clients, perhaps using a reference-counting scheme to decide when to delete the extensions. A caller can query an extensible object to see if it supports a specified extension.

The ODExtension class itself has minimal functionality. It is designed to act as a superclass class for subclasses that implement actual extension interfaces. Every extension object knows what base object it is an extension of and forwards two kinds of calls to its base object: Release calls and calls to its own interface.

### Using an Extension

To access the extension interface of an extensible part, a client, or caller, takes these steps:

1. It calls the part's override of the inherited HasExtension method to see if the extension is supported, passing the part (the base object) an extension name.

2. If the part has such an extension, the client then calls the part's (override of the inherited) AcquireExtension method to get a reference to the extension object. The part either creates the extension object or increases its reference count (if the object already exists) and passes the reference back to the client.

3. The client makes extension-interface calls directly to the extension object.

When the client has finished using the services of the extension object, it takes these steps:

1. The client calls the extension's (override of the inherited) Release method, to let the extension know that the client no longer needs it.

2. The extension, in turn, calls the (override of the inherited) ReleaseExtension method of its part (its base object) if its reference count has dropped to 0. The base object can then delete the extension.

   However, if the extension's base object has already been deleted and has called the extension's BaseRemoved method (see "Closing Your Part"), the extension cannot call its base's ReleaseExtension method.

### Implementing Extensions

Your part editors can implement any kinds of desired extension interfaces through this mechanism. The capabilities gained through extensions can be in almost any area. Examples include extensions to handle text search, spell-checking, linking, specialized text formatting, database access, and specialized graphics processing. In general, extension objects are best suited for tasks requiring high bandwidth or tight integration, for which scripting is not appropriate.

If you implement an extension object for your part, the extension should include a SOM constructor (somInit), a SOM destructor (somUninit), and an initialization (InitExtension) method. The extension could also support a GetBase method, through which a client can obtain a reference to the extension's base object. (The ODExtension class provides a default implementation for GetBase).

Your part is the factory for its extensions, which are reference-counted objects. You must follow the procedures described in "Factory Methods" when creating, managing, and deleting extensions. Also, if your part's document is closed while it has extensions remaining in memory, your part's ReleaseAll method must call the extensions' BaseRemoved method.

An extension object must always be valid (attached to its base object) to be used. If a client tries to access an invalid extension, a kODErrInvalidExtension exception is generated. Any time after your part, as base object, calls its extension's BaseRemoved method, the extension is invalid. If you want to provide your own validation scheme for extensions, you need to override the ODExtension methods CheckValid, IsValid, and BaseRemoved.

Your extension interfaces can be private to your parts, or you can establish or follow public standards. CI Labs is the agency responsible for coordinating standard extension interfaces for parts. For information on existing extension interfaces, or to propose new interfaces, please contact CI Labs at the address shown in "Cross-Platform Consistency and CI Labs".

[ Top | Previous | Next | Contents | Index | Documentation Homepage ]