The Ultimate Question of Life, the Universe, and Objects (with Apologies to Douglas Adams)

You probably already have some idea that once you have your first interface pointer for any given object, you can use QueryInterface to learn what else the object can do for you. But this begs a key question: Given a way to identify an object of a class, how do you obtain your first interface pointer to it?

This question is a central theme in this book: most chapters that follow generally deal with identifying different objects and components, the interfaces they support, techniques to obtain the first interface pointer, and what to do with the member functions of those interfaces. So the answer to this ultimate question (which is not "42," as it was in Douglas Adams's books) varies with each technology in OLE. In fact, there are four different answers to the question—four different ways to obtain that very important first pointer:

As you can see, both OLE and your own component and object implementations will involve most of these techniques at some time or other. In each case, there is also a difference in how you identify the object or component you're trying to use. Let's first look at object identity along with other object properties before we examine interfaces more closely.


Class, Type, and Prototype

The words class and type are generally interchangeable concepts and are used that way in this book. In OLE, it is often useful to view a type as a specific instance of a prototype that describes the total signature of an object as the union of its supported interfaces (which must include at least IUnknown). Thus, a class or type is a particular implementation that supports the same interfaces as other classes of the same prototype, although each class differs in many ways. For example, the compound document content object is a prototype, but chart, table, text, sound, and video classes are specific instances (types) of that prototype. The importance of a prototype is that because objects with the same interfaces are polymorphic, a client needs to understand only how to work with a prototype to work with a wide range of different specific types. Thus, a compound document container can work with any compound document content object. Such clients are implemented according to a protocol that specifies how to work with a particular prototype, and that prototype then involves multiple interfaces.