Component Object Model
 
 

object is one of those words that essentially means whatever you want it to mean. There's object-oriented programming and objects as data structures within a program. But when we talk about objects in the context of OLE 2 or ActiveX, we are referring to a very specific type of object, sometimes called a componentobject or a windowobject. These objects follow a standard called componentobjectmodel (COM). The COM standard defines the following:

  1. A common way for applications to access and perform operations on objects. This will be the subject of Chapters 3 and 4.
  2. A mechanism for keeping track of whether an object is in use and deleting it when it is no longer needed.
  3. A standard error-reporting mechanism and set of error codes and values.
  4. A mechanism for applications to exchange objects.
  5. A way to identify objects and to associate objects with applications that understand how those objects are implemented.

Why are these factors important and how do they relate to the idea of data-centric computing? Consider our ongoing example of a document containing text and spreadsheet information in which the document is opened by a word processing application. How can the word processor display a spreadsheet object it knows nothing about?

If the spreadsheet object is a COM object, it's relatively easy. The COM object can support a standard set of functions that tell an object to display itself (COM standard #1). But what does it mean when we say that an object supports a set of functions? The word processor document contains the data for the spreadsheet. (How it keeps the spreadsheet data separate from the text data will be discussed shortly.) The document also contains an object identifier that tells the system the object is a spreadsheet. (Note that it tells the system, not the word processor!) The document does NOT contain the actual functions that draw the object. Those are kept in an application or .DLL that does understand the object, in this case, the spreadsheet application.

Where does the word processing application find the spreadsheet application that contains the drawing functions? It uses the COM mechanism for finding applications that implement objects (COM standard #5). Of course, before displaying the object it may need to launch that application and allow it to access the object's data (COM standard #4). If an error occurs while the spreadsheet object is being displayed by the other application, the word processor will understand the error (COM standard #3). And when both the spreadsheet and the word processor are done with the spreadsheet object, it will be deleted (COM standard #2).

This is a vast simplification of what goes on behind the scenes, but hopefully the point is clear. The common object model makes it possible for applications to manipulate objects they know nothing about. It is the enabling technology for data-centric computing that forms the foundation for everything from future Microsoft operating systems to ActiveX controls to Visual Basic itself.

I called OLE a technological stew. So what other tasty nuggets are contained within this sauce called COM? Here is a brief list of some of the more important features of OLE.

UUID (or GUID or CLSID)

One of the key requirements of OLE is the need to be able to identify objects. When an application works with a document that contains multiple objects, it needs to be able to identify each type of object so the system can correctly identify the application that can manage the object.

To accomplish this, COM assigns every type of object a 16-byte value. This value goes by a number of different names depending on how it is used. UUID stands for Universally Unique Identifier. GUID stands for Globally Unique Identifier. CLSID stands for Class Identifier. IID stands for Interface Identifier.

When you look at a GUID in the system registry, it typically looks something like this:

{970EDBA1-111C-11d0-92B0-00AA0036005A}

Now when Microsoft calls a GUID globally unique, they aren't kidding. Once a GUID is assigned to an object, it is effectively guaranteed to be unique throughout the entire universe, forever. Two factors go into making sure the number is unique. First, part of each GUID is generated based on the network card address in your system (assuming one exists), and every network card built has a unique address thanks to industry standards relating to these cards. Second, a GUID is a very large number, so even if you don't have a network card, a GUID generator program can create a number whose odds of duplicating another are microscopically small.

Visual Basic 5.0 will create GUID numbers for your objects automatically (in fact, you'll have a greater problem cleaning up GUID numbers you don't need than in creating new ones). The important thing to remember is that the objects you create in VB are identified by the GUID-not the object name-so even if you use the same object name as someone else (something you should avoid if possible), your program will still work; it won't confuse the objects.

GUID numbers are also used to identify sets of functions called interfaces, but you'll find out about that later.

Object Presentation

OLE defines standard mechanisms by which objects can be displayed. This means that a container application, such as Microsoft Word, can allocate a space on the screen or on a printed page and allow the object to draw itself into that space. How does this happen? Word knows the GUID of the object and the standard functions the object uses for display (and other purposes). The system can search for the GUID on the registry and find the application or .DLL that contains the actual code for these functions.

But OLE 2.0 goes even farther. It defines a mechanism by which an object's application (server) can take over portions of a document container so you can use all of the tools of that application to edit the object, even though it is still within the same container. This is called in-placeediting, and a form of this mechanism is an essential part of what makes ActiveX controls work. Fortunately, Visual Basic automatically handles essentially all of the implementation details of this rather complex technology.

Object Marshaling

OLE defines a mechanism by which objects can be transferred between applications, a process called marshaling. If you are new to 32-bit programming, this may not seem to be a big issue, as it is relatively easy to transfer blocks of memory between processes in 16-bit Windows. However, you will quickly learn that transferring objects between processes is much more difficult under 32-bit Windows. Fortunately, OLE handles most of the work for you. This subject will be covered in much more depth in Chapter 6.

Windows now includes an extended form of COM called Distributed Common Object Model (DCOM). DCOM objects can be marshaled between applications running on different systems on a network.

Compound Documents (OLE Structured Storage)

If a document can contain many types of objects, how can a given container save a document? It would need to understand the file format for each of the objects, an impossible task given that the application may be totally unaware of the nature of the object or how it works. Or would it be?

OLE handles object persistence (loading and saving of objects) in the same way that it handles object display: it is the object's responsibility to know how to load and save itself from a file. Just as OLE defines a set of functions for object display, it also defines a set of functions that can be supported by an object to persist itself.

It might occur to you that this can lead to serious problems. If any one of the objects has a bug in its file I/O code, it could interfere with the portion of the file used by other objects, possibly overwriting and corrupting parts of the file. The problem of storing objects within a file is solved using an OLE technology called OLE Structured Storage. Under OLE Structured Storage, a file is divided into a hierarchy of storages and streams, where a storage corresponds roughly to a directory, and a stream corresponds roughly to a file. In effect, you have an entire file system contained within a single disk file. A container such as Word can create a storage or stream and pass it to the object, telling the object to save itself into the storage or stream. In most cases the container will also save the GUID of the object so when the document is loaded it will be able to determine the type of object that is stored in that particular storage or stream.

Figure 2.8 shows the contents of an OLE Structured Storage document created by Word for Windows (a .DOC file) containing a spreadsheet document. Storages are indicated by file folders, streams by pages. The text portion of the file is kept in a stream called WordDocument. The spreadsheet object is kept in the ObjectPool storage. The spreadsheet object in turn has as many streams of data as it wishes to use, including, in this case, streams containing summary information about the spreadsheet.