Implementing windows and COM classes

Interfaces are a very important part of COM, and they’re also the latest fad in API design. Many of the coolest new features of both COM and Windows aren’t provided through traditional Windows API functions. Instead, they’re provided by interfaces.

There are two kinds of standard interfaces. Some are implemented by the system so that you can call them. Examples include IShellLink (shortcuts) and IStorage (a new model for file I/O). You create the objects that implement these interfaces through API calls or through coclasses in type libraries. It’s a case-by-case deal. We’ll examine some specific examples later.

Other interfaces are implemented by you so that the system can call your objects. For example, if you implement IContextMenu, Windows can call your implementation to handle context menus associated with your documents. Techniques for registering or installing these interfaces vary on a case-by-case basis.

It’s unfortunate that most of the standard interfaces you might want to use have Visual Basic–hostile definitions. Here are some of the common problems with interfaces:

In short, most standard interfaces are designed for C++ and other low-level languages. High-level languages like Visual Basic and FORTRAN are out of luck. Fortunately, Visual Basic programmers who buy my book have a workaround. They can use the Windows API type library. It contains most of the standard interfaces you might want to use, but the names have been changed to protect the innocent. (The flame below takes care of the guilty.)

The Visual Basic people and the Windows and COM people don’t seem to be talking to each other. New Windows and COM interfaces keep coming out, but they’re language-specific and have no type libraries. So whose fault is it? Should the Windows and COM developers start writing Basic-friendly interfaces and type libraries? Or should the Visual Basic designers add features that allow Basic to use interfaces the way they are? Both. The origin of this problem is the split between COM Automation and the rest of COM. Automation is handled by the Visual Basic group and is mostly language-independent. The rest of COM is handled by different groups that until recently didn’t seem to realize that non-C-based languages even existed. In fact, some Windows development is done by masochists who actually do COM development in C rather than C++ (check out the samples for new Windows 95 interfaces). I see some evidence that both sides are beginning to recognize that they have a problem, but in the meantime, Visual Basic programmers are the losers.

So how do my interface definitions get around the problems discussed above? Well, I lie. I claim that unsigned integers are signed. I change the definitions so that Visual Basic understands them. My type library uses a specific type library technique to make interfaces private to the applications that use them so that they won’t overwrite the official interfaces used by other programs on your machine. Comments in the type library source files and in other documents on the CD describe the process in general. It’s a type library problem, so I won’t explain the details in this Visual Basic book.

As a Visual Basic programmer, you need to know only that the interfaces exist in the type library and that they follow a specific naming convention. I add the letters VB after the I in the interface name. So my version of IShellLink is IVB­ShellLink. My IEnumVARIANT is IVBEnumVARIANT. In theory, you can simply use the Implements statement on standard interfaces in the type library the same way you implement Visual Basic interfaces. In practice, many interfaces require workarounds and hacks. We’ll be looking at some examples in later chapters.