When to Use Which OLE Technology

Kraig Brockschmidt
Microsoft Developer Relations

February 10, 1995

What Is OLE?

There have been many answers to this question, ranging from the sublime to the ridiculous, as OLE has been identified at some time or another with each of its various sub-technologies. At one point it is all about in-place activation and document-centric computing; at another point it's all about OLE Automation and customization; then again it's all about component architectures; or perhaps it's nothing but OLE Controls.

Although each of these definitions contains some truth, they are all quite narrow perspectives. Each of them misses any conception of how all parts of OLE fit together, and what it all means. A complete definition of OLE needs to include not only the big important and marketable technologies, but also the capacity for extension and customization on all levels of the architecture. This section of the article attempts to provide a complete definition of OLE, and is specifically written for readers who are familiar with OLE terminology already.

OLE as Services

OLE, an umbrella term that includes all other OLE technologies such as OLE Controls, is made up of a number of Win32®-style application programming interface (API) functions, as well as a large number of component-object model (COM)—standard interfaces. Each interface has a fair number of functions as well. How does one make sense of this incredible mass of functionality?

There are three general classifications for all of this functionality:

  1. Access to OLE-implemented services (including many helper functions)

  2. Customization of OLE-implemented services

  3. Extension of the environment through custom services that conform to one or more of four major integration protocols: COM, OLE Automation, OLE Documents, and OLE Controls.

In other words, OLE implements a fair amount of functionality itself, and in many cases allows direct customization of that functionality through plug-in implementations of certain services. Where OLE doesn't provide a service—most of its services are very general—OLE supports the installation of custom (specific) services, making them available through the same mechanisms as the existing OLE services. With these classifications, let us define OLE as follows:

OLE is a unified environment of object-based services with the ability to both customize those services and arbitrarily extend the architecture through custom services, with the overall purpose of enabling rich integration between components.

Stated another way, OLE offers what is known as an extensible service architecture, and in addition to the architecture, OLE itself provides a number of key customizable services, one of which is the ability to create custom services of any complexity that extend the environment within the same architectural framework. All services—regardless of their complexity, point of storage, point of execution, and implementation—are globally available to all applications, to the system, and to all other services.

The collective term used to refer to all services, regardless of the source, is the word component. Software that makes use of these components is component software, the practical and consumer-oriented realization of the developer-oriented principles of object-oriented programming. It is the vision of a computing environment where developers and end users can add features to the applications they create and use simply by purchasing additional components, instead of writing such components themselves or finding more feature-laden monolithic applications.

The mechanisms used to access the functionality and information provided by a component involve the use of one or more objects, for lack of a better name. For example, a memory-management component (or service) may involve a single, simple "allocator" object that knows how to allocate, reallocate, and free blocks of memory. A complex persistent storage component may involve the use of several objects, such as objects that represent directory entities and objects that represent single file or stream entities within those directories, as well as objects that determine whether all of the information is written to a disk, memory, a database field, or wherever. OLE's extensible service architecture uses this concept of components and objects.

These "objects" are fully encapsulated units of functionality and information, where the internal implementation is absolutely irrelevant from the perspective of external clients. The encapsulation happens through what are called "interfaces" that the object provides to those clients. These interfaces form a binary standard (that is, language-independent) mechanism for accessing objects and is critical and is the most fundamental standard for interoperability in OLE, also providing the ability to treat different objects from different components polymorphically and the ability to reuse implementations of interfaces between objects and components.

So any given service, or component, will be some collection of object types, each with some specific sets of interfaces that are accessed in a particular way. These vary greatly from service to service. If you want to access and use a particular service, you need to know what type of objects provide that service, who implements the objects, and the mechanism for creating instances of the objects or accessing already-running instances. If you want to customize a service, you have to know what kind of objects you must implement yourself and how to plug those objects into the architecture of that service. If you want to create your own service, you must know what objects are necessary and the interfaces on those objects that are important. OLE defines a number of standard extensions, such as Drag and Drop, OLE Documents, and OLE Controls, where the objects you provide must implement a certain set of interfaces. For services where Microsoft or third-party standards groups have not defined standard extensions, you can create your own interfaces and your own rules.

Historically, the lack of concise differentiation between who does what for which services has caused a great deal of confusion, both inside and outside of Microsoft. For example, a good deal of literature attempts to ask who implements this or that interface, when the real question is who implements this or that service and what objects and interfaces are used to access that service. The confusion is that interface, and sometimes object, is used interchangeably with service, when a service can easily have multiple objects that each have multiple interfaces. (There is a lot of confusion about whether objects are equivalent to interfaces. In an article on OLE Automation, page 42 of Software Development, November 1992, Andy Barnhart reveals this basic confusion: “When you speak of an object in OLE Automation, what you are really referring to is an IDispatch interface or a dispatch interface. In OLE, every object is really an interface of some kind.” This is dead wrong as far as COM and OLE are concerned.) In some cases, it is true, a service will have one object and one interface, but this is not a good general definition. It also doesn't make sense in many cases to talk about the implementation of an interface, because the objects in many services are entirely replaceable with custom implementations.

So to understand the differences between services and their interfaces, let's look at the specific services that OLE provides, how those services are customized, and what it means to have a custom service. With that defined, we'll be in a position to determine just how to apply OLE to any particular project.

OLE-Implemented Services and Customizations

OLE provides a sizable number of services and allows customization of the following services:

Appendix A lists these services along with the specific API functions and interfaces that expose that service, as well as the interfaces and API functions that allow customization. Appendix B goes further to list almost all of the OLE interfaces and API functions and their purposes.

Custom Services

How, then, is the service environment extended? In the list above there is an entry called "Service Management." This is an OLE service that exists solely for the purpose of managing custom services. This particular management is a fixed process—one that is implemented inside the OLE libraries and one that clients of services can always depend upon. Therefore the process of creating instances of components in and of itself that doesn't provide for much customization. However, the variety (types) of services that can work within this management scheme is entirely open and arbitrary. Clients can depend on a standard process to access services, and those services can still be very rich.

A new service or component is an implementation of an object, with any interfaces it requires to provide its services, structured within a "server module" (.DLL or .EXE) as required by OLE's management mechanisms. As is well documented, this server module must provide a class factory that is associated with the CLSID of the service, where that class factory creates the objects through which external clients access the service. The class factory is then something of a service itself. The server module also makes provisions for unloading itself. The mechanisms through which a server exposes its class factory and provides for unloading tie directly into specific OLE API functions for service management.

Where the entire business of class factories is integral to building a component, the component itself has, at its root, some object class (the class associated with the CLSID). The component may involve multiple objects, but only one object is accessed through the class factory. In any case, all objects in the component can implement basically any set of interfaces, whatever suits the purpose. Each interface has its own rules for how a client of the component accesses that service.

In some circumstances, the component is intended to fit into a standard integration protocol where the expected behavior of that component spans a set of interfaces instead of a single interface. At this time there are three such protocols: OLE Automation (methods, properties, programmatic control of UI), OLE Documents (compound documents made of unstructured information, linked or embedded), and OLE Controls (methods, properties, events, layout, and UI interaction inside a form). In each case the object (or objects) is structured inside a server module as a custom service—the differences lie completely in the interfaces implemented on the object, the client-side interfaces in the container (controller, document, form, and so on), the expected interaction between object and container, and the user interface standards through which end-users work with such components. An automation object may provide a service like the programmatic control of a hardware board in the computer without any UI; a compound document object may provide a charting or picture drawing service such that the container doesn't have to understand charts or drawing itself; a control might provide a text editing, push button, or label service. The type of service generally determines the appropriate protocol.

Of course, many components won't fit into one of these three protocols and thus implement whatever interfaces are appropriate, which may include custom interfaces. In all these cases the expected behavior of a component is specific to whatever interface is in use—there is no higher protocol that spans a set of interfaces. Whatever the case may be, there are many standard OLE interfaces that are applicable to specific functionality, such as IDataObject, IViewObject, and IPersist*. Where a standard interface doesn't exist for the needed task, objects can support any number of custom interfaces. This involves not only publishing the interface (header file or type library) but when custom interfaces are supported across process boundaries, the service is also responsible for providing marshaling support (standard or custom marshaling). This marshaling support is made of plug-in customizations (in the form of other objects, of course) to OLE's built-in remoting service. This level of customization occurs transparently to both the component and the client of the component.

Applying OLE

It has been a perpetual problem to describe just how an application might "do OLE." How does an application become an "OLE Application"? The answers have not always been clear, and depend on who you talk to. Some would say you should support OLE Documents, others OLE Automation, others OLE Controls. Or they tell you to use Compound Files and create a Summary Information stream, or to support Drag and Drop. In almost all cases, an "OLE Application" from a marketing perspective generally means that an application uses OLE in some way that is visible to the end user—the idea is that end users will start to demand "OLE" in all their applications and thus we get a proliferation of the technology. This is an appropriate policy for things like the Windows® 95 logo program.

However, in order to make OLE truly successful in realizing a vision of component software, the use of OLE in software products must go deeper than just user interface (UI) features. It must permeate all levels of software development, a process that includes empowering end users to essentially write their own custom applications using available services, where those services themselves use other lower-level services.

In the short term of the next few years, "OLE Applications" will fall into two categories: applications that use only the available OLE services/components, and applications that provide components themselves. In the long term the latter category becomes much more important and involves the process of "componentization." The next two sections of this article describe these two categories in more detail, with the second including something approaching a component design guide.

Using OLE Components

OLE has some very powerful services that are applicable outside of most other services. For example, an application can use Compound Files as its native storage mechanism. An application might use the OLE clipboard service instead of using the Win32 API for the same feature, and it might use OLE Drag and Drop to gain integration with the system shell and other data-bearing applications. An application might also simply use OLE's default task allocator for memory management instead of lugging around its own proprietary implementation.

Whatever the case may be, an application in this category is simply using some of the OLE API and the interfaces involved to implement some feature as it would any other part of the Win32 API. To determine which OLE technology to use, application designers simply determine which features they want and check if OLE provides the means to implement those features. If so, they incorporate at least these parts of OLE in that application. With some OLE services, the application may need to customize that service, or implement objects (ones without CLSIDs or server modules) that interact with that service, such as with Drag and Drop.

Into this category we might also put those applications that are clients of custom services: OLE Automation Controllers, OLE Document Containers, and OLE Control Containers. Although these applications can make use of the custom services in these protocols from other sources, they do not implement custom services themselves. These client applications use OLE's "Service Management" facility to instantiate or initially access the objects from the other sources, then incorporate them into documents or forms through the standard interfaces such as IDispatch, IOleObject, and IOleControl.

In time, the total number of controller or container applications will be very small compared to the total number of available custom services. Many years from now there might only need to be a single container that can fully integrate any custom service, including language modules (for customization of the language used to write automation scripts) and document/form templates (for customization of document or form types). These plug-in modules would just be custom services themselves. This is not yet a reality because the necessary interfaces have not been designed nor researched, and such work takes a considerable amount of time. But in time they will happen.

"Componentization" (Also Called "OLE-Factoring")

Although making simple use of OLE services (as described in the previous section) is a viable way to create an "OLE Application" today, the long-term view is one where only one such client application exists and everything else provides one or more custom services, or "components." The process of "componentization" is one in which today's applications are broken up into individual services that can then be used from any other client application. Over time this means a diminishing number of client applications, through either consolidation or just plain obsolescence. Everyone should understand the direction that component software is headed, and not bet much of their future on selling clients. What, then, is "componentization"?

Componentization is the thorough process of breaking any piece of software into functional components where those components are useful to developers and end users alike.

Componentization, over time, is essential to the success of component software in that such a process yields a diversity of components, a rich set that varies in scale and target user. When the end user is included as a target, componentization can create new markets and new revenue, and that is the compelling reason for anyone to undertake this sort of process.

Componentization involves both design and implementation and can be summarized in the following seven steps. The first step is to find the objects; all remaining steps are applied to each object in turn.

  1. Determine what conceptual "objects" or "services" you wish to expose to both developers and end users. Services that are useful to low-level programmers include function libraries and controllable subroutines. Certain mid-level controllable pieces, such as "business objects," are more useful to a corporate developer. High-level objects such as controls, charts, graphics, text, and other information- or UI-intensive elements are very useful to end users and to some corporate developers. Remember to keep in mind the types of elements that would enable end users to write their own custom applications.

  2. For each object, determine its content, its information that might be of interest to clients. Determine how this information is best exposed. Is it a data structure with a defined format (such as CF_TEXT or CF_METAFILEPICT)? Could it be considered "unstructured," such that it might be incorporated into a compound document? Is it best manipulated through individual properties? Can the content be viewed and printed? Is the content persistent?

  3. Determine its "functionality," excluding data exchange and specific "action" verbs. Is the functionality best exposed as a simple library? Should the functions be early-bound or late-bound? Does the object have events it would like to fire (that is, outgoing functionality) in response to hardware or software changes or end-user manipulations?

  4. Determine the desired UI through which you will allow end users to manipulate both content and functionality. Is content something that can be put on the Clipboard or exchanged through Drag and Drop? Is content a set of properties that can be edited in property pages? Is content manipulation tied to the execution of functional "actions" (verbs) such as "play," "edit," and "rewind"? Is content best manipulated directly in a window through mouse clicks and keystrokes, perhaps including menu commands and toolbars and tool palettes?

  5. Use Tables 1, 2, and 3 (below) to match up content, functionality, and UI mechanisms desired with the applicable and appropriate OLE technologies. Then consult Table 4 to check the object-side interfaces required.

  6. Determine if the object will need to use any other objects or services itself. For each service or technology, check Table 4 below for the client-side requirements of that service. In many cases an object that is a client of another will have to implement additional client-side interfaces. Note, however, that those interfaces are not part of the exposed object-side service.

  7. Implement the service by implementing the object(s) and the necessary surrounding structures to plug into OLE. Implement certain features using OLE services where applicable, and implement other small objects (these are not services) that support customization of OLE as necessary. Be sure to pay attention to other implementation and deployment details such as server module type, registration, licensing, compatibility, and so on.

Why "Componentization" Is Important

OLE enables the integration of components through different relationships, from low-level relationships to high-level relationships. In order to integrate components, you must first have components. The process of componentization is the structuring of functionality and content into meaningful packages, from the very simple groups of library functions to complex but very rich compound document objects and controls. But while OLE enables the integration, independent software vendors (ISVs) must provide the components to integrate.

It is not good enough to ask ISVs to just break up an application into components for the sake of easing the development process for other ISVs. This is the promise that "object-oriented programming" and "object technology" have both failed to deliver in any real abundance. The "object" experts have failed to address the most fundamental question: Why should the customer care? Revolutionizing the development process was a promise with dynamic-link libraries (DLLs), once upon a time. That, too, failed. Dynamic date exchange (DDE) had some hope of making programmable applications. That failed. OLE 1.0 had the hope of making compound documents and document-centric computing. That made more progress, but still didn't cause any significant change. Before OLE 2, VBXs caused the most significant change, because they put the power of programming applications closer to the hands of the people who would use those applications. That is, VBXs empowered more corporate developers, who create more specific applications for their end users than ISVs necessarily can.

OLE, including COM, Automation, OLE Documents, and OLE Controls, is a unified architecture that can empower not only ISVs with reusable low-level components, but can also empower corporate developers with automation objects and controls, and even empower end users with controls, compound document objects, and automation objects to some extent.

Componentization will not succeed if it is done simply for the sake of breaking a large application up into "reusable objects" (the chant of traditional object-oriented programming), because for the potentially large cost of restructuring an application there is hardly any benefit to the end user and there is hardly any potential for increasing the application's market or customer base. Componentization will most surely fail if object-orientation for the exclusive benefit of the programmer is the goal. To be successful, the process must generate building blocks for programmers of all types, because that motivates the final consumer, the end-user, to individually decide to purchase your components, and it is only from those consumers that software publishers earn their livelihood!

The key to making this all work is generating a large number of components and a fair number of tools that can integrate those components. Different components are useful to different developers or customers. Different tools targeted for different problems and different users are necessary, just as the components those tools use are varied. Because the ability to integrate is limited by one's container, so in order to make integration more powerful there must be strong containers and strong components. Such components, tools, and containers are not something that a single company can build by itself; it requires the involvement of everyone in the industry. Component software is a tremendous challenge and opportunity.

Table 1. Mappings from Content Mechanisms to OLE Technologies

Content Category Technology
Get/Set of formats-specific properties Uniform Data Transfer
Get/Set of single properties (class-specific properties) OLE Automation, Property Change Notification
Embedding of unstructured information OLE Documents, Embedding
Linking to unstructured information OLE Documents, Linking
Ability to display and print graphical presentations Viewable Objects (inherent in OLE Documents)
Persistence of information Persistent Objects (inherent in OLE Documents)

Table 2. Mappings from Functionality Mechanisms to OLE Technologies

Functional Category Technology
Incoming Functions, v-table binding (early or late) Standard interfaces where applicable, custom interfaces where necessary (described in header file or type library)
Incoming Functions, dispatch binding (early or late) OLE Automation (described in type library)
Outgoing Functions, any binding Connectable Objects

Table 3. Mappings from UI Mechanisms to OLE Technologies

UI Category Technology
Content: Direct manipulation of object properties Property Pages
Content: Separate Window Activation of embedded and linked content OLE Documents (all types)
Functionality: Access custom actions (functional verbs) OLE Documents (all types)
Content: In-Place Activation of embedded content OLE Documents In-Place Activation
Content: Direct manipulation of object data in its own UI OLE Controls
Functionality: Transformation of end user actions into events OLE Controls

Table 4. Service/Object- and Client-Side Interfaces for OLE Technologies

OLE Technology Service/Object-Side Interfaces Client-Side Interfaces
Connectable Objects On object: IConnectionPointContainer, IProvideClassInfo; on sub-objects for each outgoing interfaces: IConnectionPoint For each connected outgoing interface, client provides a sink object with that interface
Custom Interfaces Custom interface Depends on design of the custom interface; the custom interface may require other custom interfaces on the client side
Uniform Data Transfer IDataObject, IEnumFORMATETC Sink object with IAdviseSink (for data changes)
Viewable Objects IViewObject (in-process objects only) Sink object with IAdviseSink (for view changes)
Persistent Objects IPersistStorage, IPersistStream[Init], IPersistFile None
Naming and Binding IPersistFile, IOleItemContainer, IParseDisplayName None
Property Change Notification Same as Connectable Objects with an IPropertyNotifySink connection point Sink object with IPropertyNotifySink
OLE Automation for Properties and Methods IDispatch, optionally IProvideClassInfo None
Property Pages On object: ISpecifyPropertyPages; Associate objects: IPropertyPage[2], IPerPropertyBrowsing Page Frame: IPropertyPageSite (usually provided through OLE's standard frame)
OLE Documents, Embedding IOleObject with IDataObject and IPersistStorage for EXE servers, IViewObject, IOleCache[2], and IOleCacheControl additional for DLL servers (for DLLs, most interfaces come from default handler or cache) Embedding Site: IOleClientSite, IAdviseSink
OLE Documents, Linking DLL servers: same requirements for embedding plus IOleLink (implemented in the default handler). EXE servers: IOleObject, IDataObject, plus interfaces to resolve monikers, usually IPersistFile and IOleItemContainer implementations Linking Site: IOleClientSite, IAdviseSink (an in-process handler acting as a client to a local server will implement IAdviseSink2. Normally this is the default handler)
OLE Document, In-Place Activation IOleInPlaceObject, IOleInPlaceActiveObject Frame: IOleInPlaceFrame; Document (if applicable): IOleInPlaceUIWindow; Embedding Site: IOleInPlaceSite
OLE Controls All interfaces required for embedded object with in-place activations plus IOleControl. A simple frame control that contains other controls has ISimpleFrameSite. Embedding Site: IOleControlSite, IDispatch (for ambient properties); Event Sinks: IDispatch or other vtable interface depending on event set. May also include extended control implementations of various control-side interfaces.

Appendix A. OLE-Implemented Services and Customizations

Service Access Mechanism Customization
Task Memory Allocation API functions: CoGetStandardMalloc and CoGetMalloc; Interfaces: IMalloc A custom task allocator (IMalloc) can be installed with CoInitialize (or OleInitialize) on most OLE implementations. CoGetMalloc accesses the currently installed allocator, default or custom, in this scenario.
"Remoting" of Interface Calls (Standard interfaces) None—"remoting" is automatic Custom interfaces require custom "remoting" support, but this is an issue for custom services, not OLE implemented services.
Concurrency Management (incoming calls, time-outs, etc.) None: default management is installed automatically. A custom filter object with IMessageFilter is installed with CoRegisterMessageFilter and allows full control over concurrency.
Service Management API functions such as CoCreateInstance, registration functions. Interfaces vary While the creation and registration processes are fixed, the services that can be installed to work with the processes are completely open.
Type Libraries Creation: API functions such as CreateTypeLib and the ICreateTypeLib and ICreateTypeInfo interfaces

Manipulation: API functions such as LoadTypeLib to load, interfaces ITypeLib, ITypeInfo, and ITypeComp to navigate

None: OLE implementations always used.
Compound Files API functions: StgCreateDocfile, StgOpenStorage, etc.

Interfaces: IStorage, IRootStorage, IStream interfaces

By default, Compound Files writes to a disk file through a default "LockBytes" object (ILockBytes). A custom LockBytes can redirect the information to a different byte-array device. Such an object is installed with a function like StgCreateDocfileOnILockBytes. In the future, installable file systems will be custom implementations of IStorage and IStream.
Naming and Binding API functions CreateFileMoniker, CreateItemMoniker, etc.

Interfaces: IMoniker, IBindCtx, IParseDisplayName, IOleItemContainer, etc.

A custom moniker (an object with IMoniker) is polymorphic with any OLE-provided moniker; that is, all monikers are interchangeable as far as their interfaces are concerned. A server implements various interfaces to assist in the binding process.
Running Object Table API Function: GetRunningObjectTable; Interface: IRunningObjectTable None—the OLE implementation of this service is always used.
Default Automation Object (wrapper) API function: CreateStdDispatch; interface: IDispatch None—a fully customized automation object doesn't use the default wrapper implementations
Type Conversion (OLE Automation) API functions: Variant* None; no need for it.
Safe Arrays (OLE Automation) API functions: SafeArray* None; no need for it.
String Manipulation (OLE Automation) API functions: SysAlloc* None; no need for it.
OLE Clipboard API functions: OleGetClipboard, OleSetClipboard, etc.

Interface IDataObject, IEnumFORMATETC.

For pasting, none. For sourcing, you provide the implementation of the data object (IDataObject) that is conceptually "on" the Clipboard.
OLE Drag and Drop None Drag and Drop requires the presence of a custom source and a custom target to perform any transfer operation. The source and target are notified of various important events during the operation as OLE tracks the movement of the mouse and changes in the keyboard state.

The source is an object that implements IDropSource. That object and a data object is given to the API function DoDragDrop to start an operation. The target is an object with IDropTarget that is installed with RegisterDragDrop and removed with RevokeDragDrop.

"Advise Holders" (simplify management of multi-cast notifications) API functions CreateDataAdviseHolder and CreateOleAdviseHolder

Interfaces I[Data<!--htmlstart-->&#124;<!--htmlend-->Ole]AdviseHolder

None: these services are always generic and there is no need for custom implementations.
Standard Property Frame (displays property pages; OLE Controls) API functions OleCreatePropertyFrame[Indirect]

Interface: IPropertyPageSite

A custom property frame is some custom object with IPropertyPageSite. This does not tie into the API in any way.
Default Data Cache (OLE Documents only) API function CreateDataCache Custom caching is accomplished through aggregation on the default cache. This occurs generally in in-process compound document servers.
Default Object Handler (OLE Documents only) API functions: OleCreateDefaultHandler

Interfaces vary

A custom handler will typically aggregate on the default handler, letting it handle most in-process compound document services.
Standard Font and Picture Objects (from OLE Controls) API functions: OleCreate[Font <!--htmlstart-->&#124;<!--htmlend--> Picture]Indirect

Interfaces: IFont, IPicture

None—these are provided simply as a convenience. Their use is not required.
OLE 1 and 16/32 Compatibility Usually Automatic, API functions handle conversion of storage None—run-time compatibility is handled automatically and transparently; storage compatibility is a manual process using helper functions.
Helper Functions Varies None—OLE provides helper functions to make programming more convenient.

Appendix B: The Purpose of All OLE APIs and Interfaces

OLE is a set of implemented services, mechanisms to customize those services, and mechanisms to install custom services according to various protocols. Every OLE API function and every currently defined interface (that is, those found in shipping OLE technologies) has a purpose in this framework. The table below lists each API function and interface, along with its purpose, be it a service, a customization, or a mere helper or wrapper function. This helps to illustrate why the various APIs and interfaces exist. (Note that the collection of functions in the OLE UI library is not included at this time. Some recently added interfaces are also missing.)

Function or Interface Purpose
General
IUnknown Control of object lifetime, interface negotiation. Ubiquitous for any component regardless of implementation. QueryInterface exposes incoming interfaces.
IEnum* Enumeration of various types of lists. Used in many cases throughout OLE.
IProvideClassInfo Expose the type information about an object's incoming and outgoing interfaces.
IConnectionPointContainer, IEnumConnectionPoints, IConnectionPoint, IEnumConnections Expose an object's outgoing interfaces
Initialization, Memory Mgmt.
CoBuildVersion, OleBuildVersion Check OLE library version numbers
IMalloc Task memory allocation
CoInitialize, CoUninitialize, OleInitialize, OleUninitialize Initialize/Uninitialize COM/OLE libraries and install an OLE-provided task allocator (most OLE implementations also allow installation of a custom allocator).
CoCreateStandardMalloc Access standard task memory allocator
CoGetMalloc Access currently installed task allocator
"Remoting"
IExternalConnection Notification: connection/disconnection from remote process
CoLockObjectExternal Lock a remote object implementation
CoDisconnectObject Forcibly disconnect any remote connections
IMarshal Standard marshaling (OLE impl); custom marshaling (custom impl)
CoGetStandardMarshal Access standard implementation of IMarshal
IStdMarshalInfo Support for Custom Interfaces
CoMarshalHresult, CoUnmarshalHresult, CoMarshalInterface, CoUnmarshalInterface, CoReleaseMarshalData Helpers for marshaling both standard and custom. CoMarshalInterface, for example, is always called whenever any object needs to create the server-side remoting support for an interface pointer to a new object. CoUnmarshalInterface creates the client side to match.
CoIsHandlerConnected Helper to determine if an in-process component is connected to a remote process.
Custom Interface Installs a custom IMessageFilter implementation.
IMessageFilter Helper functions for OLE 1 container document compatibility.
CoRegisterMessageFilter Concurrency management handling interface. A default implementation is always installed when remoting occurs
Custom Services
CoCreateInstance Access custom component implementation given a CLSID
IClassFactory[2] Creation of custom component based on CLSID
CoGetClassObject Access custom class factory implementation given a CLSID
DllGetClassObject Expose a custom class factory implementation from a DLL
CoRegisterClassObject, CoRevokeClassObject Install/remove a custom class factory implementation
Service Registration
CoCreateGuid, IsEqualGUID, IsEqualIID, IsEqualCLSID Helper for creation and comparison of GUIDs
DllRegisterServer, DllUnregisterServer Expose self-registration functionality from a DLL server module.
CoGetTreatAsClass, CoTreatAsClass, OleDoAutoConvert, OleGetAutoConvert, OleSetAutoConvert, GetConvertStg, SetConvertStg Conversion/Emulation manipulation (only customization is registry information that describes which classes are interchangeable)
DLL Server Management
DllCanUnloadNow Control DLL server unloading
CoLoadLibrary, CoFreeLibrary, CoFreeAllLibraries, CoFreeUnusedLibraries Load and unload in-process server modules
Misc. COM Functions
CLSIDFrom[ProgID <!--htmlstart-->&#124;<!--htmlend--> String], [ProgID <!--htmlstart-->&#124;<!--htmlend--> String]FromCLSID, IIDFromString, StringFromIID, StringFromGUID2 Helper functions for conversion between GUIDs, strings, and ProgIDs.
CoGetCurrentProcess Miscellaneous helper
CoDosDateTimeToFileTime, CoFileTimeToDosDateTime, CoFileTimeNow Miscellaneous helper functions for date/time conversion. (More appropriate to be a Win32 API.)
IsValidIid, IsValidInterface, IdValidPtrIn, IsValidPtrOut Miscellaneous validation functions (16-bit only)
Naming, Monikers
IMoniker Exposes moniker functionality. OLE provides five moniker implementations (five different classes). Custom implementations can be exposed via object creation functions or custom API..
BindMoniker Wrapper for IMoniker::BindToObject
CreateFileMoniker, CreateItemMoniker, CreateAntiMoniker, CreatePointerMoniker, CreateGenericComposite Access OLE standard moniker implementations
IParseDisplayName Implemented on a custom object to parse a user-readable display name into a moniker object, standard or custom.
IOleContainer, IOleItemContainer While generally related to OLE Documents, these interfaces are implemented on an object that contains items and is necessary to bind item monikers.
IBindCtx Implemented on the OLE standard "bind context" object.
CreateBindCtx Instantiates a bind context object returning an IBindCtx pointer.
IRunningObjectTable Exposed from the OLE implemented "running object table" service. No customizations.
GetRunningObjectTable Access the running object table.
MkParseDisplayName Converts a string into a moniker which includes the intelligence to determine whose implementation of IParseDisplayName to use.
MonikerRelativePathTo, MonikerCommonPrefixWith Helpers to manipulate file monikers to create absolute and relative paths using IMoniker::RelativePathTo and IMoniker::CommonPrefixWith.
Structured Storage
IStorage Expose storage object functionality (directory)
IStream Expose stream object functionality (files)
IRootStorage Control underlying file attached to an IStorage in a Compound File
ILockBytes Customize underlying storage medium in a Compound File
StgCreateDocfile, StgOpenStorage Create or open OLE's Compound File (IStorage/IRootStorage) implementation using default file-based ILockBytes implementation
StgCreateDocfileOnILockBytes, StgOpenStorageOnILockBytes Create or open OLE's Compound File (IStorage/IRootStorage) implementation using a custom ILockBytes implementation.
StgIsStorageFile, StgIsStorageILockBytes Check if a file is a Compound File with the default implementation of ILockBytes or a custom implementation.
CreateILockBytesOnHGlobal, GetHGlobalFromILockBytes Access memory-based ILockBytes implementation.
CreateStreamOnHGlobal, GetHGlobalFromStream Access memory-based IStream implementation
[Read <!--htmlstart-->&#124;<!--htmlend--> Write]Class[Stg <!--htmlstart-->&#124;<!--htmlend--> Stm], [Read <!--htmlstart-->&#124;<!--htmlend--> Write]FmtUserTypeStg, GetClassFile Retrieve or save CLSID, data format, and user type information to a storage or stream.
StgSetTimes Helper function to manipulate Compound File timestamp
Persistent Objects
IPersist, IPersistFile, IPersistStorage, IPersistStream[Init] Expose from a persistent object based on storage model: file-based, IStorage-based, IStream-based (with or without initialization).
Notifications/Events
IAdviseSink[2] Receive notifications of data change, view change, compound document object changes
IPropertyNotifySink Receive notifications of property changes and control overrideable changes.
Events sets Interfaces defined by an object, implemented by an outside event sink.
Uniform Data Transfer
IDataObject, (IAdviseSink), IEnumFORMATETC Expose ability to exchange formatted data structures and notify an advise sink of data changes.
OleDuplicateData Helper function for copying data structures
ReleaseStgMedium Helper to free data structures
Viewable Objects
IViewObject[2], (IAdviseSink) Expose ability to draw visual presentations to device contexts and notify an advise sink of view changes
OleDraw Simple wrapper around IViewObject::Draw
OleGetIconOfFile, OleMetafilePictFromIconAnd-Label, OleGetIconOfClass, Helper function for manipulation of iconic views of objects.
OleTranslateColor Helper to translates between COLORREF and OLE_COLOR types
Standard Types
IFont, IFontDisp Expose standard font object implementation (OLE Controls)
OleCreateFontIndirect Access standard font object implementation
IPicture, IPictureDisp Expose standard picture object implementation (OLE Controls)
OleCreatePictureIndirect Access standard picture object implementation
OleLoadPicture Create a picture object from stream information
OleIconToCursor Helper function to turn an icon into a cursor for simple Win32 API based drag and drop (not OLE drag and drop)
OLE Clipboard
OleSetClipboard, OleGetClipboard, OleFlushClipboard, OleIsCurrentClipboard API for clipboard handling service via IDataObject. No customization except for whatever IDataObject implementation is involved.
OLE Drag and Drop
IDropSource Exposes source-side functionality in a drag-and-drop operation.
IDropTarget Exposes target-side functionality in a drag-and-drop operation.
DoDragDrop Installs IDropSource (and IDataObject) implementations to begin a drag-and-drop operation
RegisterDragDrop, RevokeDragDrop Installs/uninstalls a drop target implementation. Drop target is exposed to DoDragDrop only.
Type Libraries
ITypeLib, ITypeInfo Standard OLE implementations to navigate through a type library structure
ITypeComp Standard OLE implementation to bind to interface functions defined in a type library in a much more efficient manner, useful for compilers
LHashValOfName[Sys] Create a hash value used in ITypeComp functions
LoadTypeLib, LoadRegTypeLib, LoadTypeLibFromResource, RegisterTypeLib, QueryPathOfRegTypeLib Helpers for registering and loading a type library. Loading a type library means instantiating the type library object with ITypeLib on it. In other words, Load[Reg]TypeLib[FromResource] accesses the standard ITypeLib implementation.
CreateTypeLib Creates a brand new type library (as opposed to loading an existing one). The type library implements ICreateTypeLib. Generally used from type library compilers.
ICreateTypeLib, ICreateTypeInfo Implementations in OLE for creating a type library. Used from type library compilers.
CreateDispTypeInfo Create a type information object with ITypeInfo based on INTERFACEDATA structures
CompareStringA, LCMapStringA, GetLocaleInfoA, GetStringTypeA, GetSystemDefault[LangID <!--htmlstart-->&#124;<!--htmlend--> LCID], GetUserDefault[LangID <!--htmlstart-->&#124;<!--htmlend--> LCID] Helper functions for working with locale-specific information in OLE Automation. These are primarily for Win16 platforms as the same functions are part of the standard Win32 API.
OLE Automation
IDispatch, IEnumVARIANT Expose methods and properties through a dispatch (DISPID) mechanism as well as "collections"
CreateStdDispatch Install a custom interface into a standard IDispatch implementation. In other words, access a standard IDispatch that internally depends on a custom interface implementation.
DispGetIDOfNames, DispGetParams, DispInvoke Helper functions for direct implementations or uses of IDispatch.
RegisterActiveObject, RevokeActiveObject, GetActiveObject Helper functions to register automation objects as running and access running object. Basically wrappers around the running object table.
SafeArray- AccessData, AllocData, AllocDescriptor, Copy, Create, Destroy, DestroyData, DestroyDescriptor, GetDim, GetElement, GetElemSize, GetLBound, GetUBound, Lock, PutElement, Redim, UnAccessData, Unlock Helper functions for manipulating arrays passed through IDispatch
Sys- AllocString, AllocStringLen, FreeString, ReAllocString, ReAllocStringLen, StringLen Helper functions to manipulate BSTR types
Variant- ChangeType[Ex], Clear, Copy, CopyInf, Init, TimeToDosDateTime; (DosDateTimeToVarantTime) Helper functions to manipulate variables passed in VARIANT structures, such as type conversion and duplication.
OLE Property Pages
OleCreatePropertyFrame-[Indirect] Access standard implementation of a property page frame that implements IPropertyPageSite.
IPropertyPageSite Expose capability as a property page frame.
ISpecifyPropertyPages Expose CLSIDs of an object's property pages (which are separate objects).
IPropertyPage[2] Expose property page functionality.
IPerPropertyBrowsing Expose the ability to manipulate individual properties
OLE Documents, General
OleRegGetUserType, OleRegGetMiscStatus, OleRegEnumFormatEtc, OleRegEnumVerbs Helper functions for default registry handling (OLE Documents, mostly)
IRunnableObject Notifications of when an object is going between loaded and running.
OleIsRunning, OleLockRunning, OleRun, OleNoteObjectVisible, OleSetContainedObject Helpers for control of running objects in compound documents. Most of these functions call IRunnableObject members.
IOleAdviseHolder Helper functions for managing IAdviseSink pointers from within a compound document object implementation.
CreateOleAdviseHolder Access OLE implementation of IOleAdviseHolder object. No customization
OleLoad, OleLoadFromStream, OleSave, OleSaveToStream Functions to load and save compound document objects in IStorage or IStream instances. Wrappers for IPersistStorage and IPersistStream calls.
OleCreateStaticFromData Access OLE implementation of a static object
OLE Documents: Handlers and Caching
OleCreateDefaultHandler, OleCreateEmbeddingHelper Access OLE implementation of default handler or "embedding helper" (a cut-rate default handler for same-process objects).
IOleCache[2] Implemented by default provided by OLE, in-process handlers and servers in compound document uses can customize.
CreateDataCache Access OLE's data cache implementation (service). Cache object implements a number of interfaces including IOleCache[2], IOleCacheControl, IDataObject, IViewObject[2], and IPersistStorage.
IOleCacheControl Implemented in OLE's default handler to access remote server's IDataObject implementation. Used in OLE Documents
OLE Documents: Embedding
IOleObject Expose compound document object functionality
IOleClientSite Provide container-side information and functions to compound document objects
OleCreate, OleCreateFromData, OleCreateFromFile; OleQueryCreateFromData Access custom implementations of embedded compound document objects depending on where the source information exists). OleQueryCreateFromData checks if OleCreateFromData will work.
OLE Documents: Linking
IOleLink Expose from in-process implementations of linked compound document objects (usually taken from OLE's default handler).
OleCreateLink, OleCreateLinkFromData, OleCreateLinkToFile; OleQueryCreateLinkFromData Access custom implementations of linked compound document objects depending on where the source information exists). OleQueryCreateLinkFromData checks if OleCreateLinkFromData will work.
IOleContainer, IOleItemContainer Enumerate objects within a generic container (usually compound document container, but not necessarily). IOleItemContainer supports the additional step of binding an item moniker.
OLE Documents: In-Place Activation
IOleInPlaceObject, IOleInPlaceActiveObject Expose object-side functionality for in-place activation support (interfaces derive from IOleWindow)
IOleInPlaceFrame, IOleInPlaceUIWindow, IOleInPlaceSite Expose container-side functionality for in-place activation support (interfaces derive from IOleWindow)
OleCreateMenuDescriptor, OleDestroyMenuDescriptor, OleSetMenuDescriptor, OleTranslateAccelerator OLE-provided helper functions for in-place activation.
OLE Documents: OLE 1 Compatibility
CoIsOle1Class Helper to check if a class is an OLE 1 compound document object.
OleConvertIStorageToOLE-STREAM[Ex], OleConvertOLE-STREAMToIStorage[Ex] Helper functions for a container providing compatibility with OLE 1 compound documents.
OLE Controls
IOleControl Expose OLE Control specifics to a container dealing with keyboard mnemonics and ambient property changes.
IOleControlSite Expose OLE Control Container specifics to an OLE Control.
ISimpleFrameSite Expose an OLE Control that is merely a visual frame around a set of other controls that filters messages going to the controls within it to provide group behavior for a set of controls (like radio buttons).