Kraig Brockschmidt
Microsoft Developer Relations
February 10, 1995
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, 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:
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 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.
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.
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.
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.
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.
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. |
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-->|<!--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-->|<!--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. |
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-->|<!--htmlend--> String], [ProgID <!--htmlstart-->|<!--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-->|<!--htmlend--> Write]Class[Stg <!--htmlstart-->|<!--htmlend--> Stm], [Read <!--htmlstart-->|<!--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-->|<!--htmlend--> LCID], GetUserDefault[LangID <!--htmlstart-->|<!--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). |