Calling IDispatch: A Simple Automation Client

After reading Chapter 14, you should already understand much of what a controller will do when it calls an object's automation interfaces. Here we can take a look at this topic from the controller's point of view. First we'll examine the initialization steps involved in creating the object, loading an LCID, retrieving its type information, and finding the object's help directory. Then we'll look at calling the IDispatch member functions GetIDsOfNames and Invoke. We won't deal with type information because that is outside the scope of this sample. Calling IDispatch functions means that we're dealing with a dispinterface but not the custom part of a dual interface. To call the latter, either we'd hard code the vtable offsets by including the IBEEPER.H file from the Beeper4 sample in Chapter 14, or we'd have to manually build the correct stack frame based on type information. We'll look at a process such as this later, but it is not demonstrated by a sample program in this book. Finally we'll look at how a controller handles exceptions that come back from IDispatch::Invoke.

The AutoCli sample discussed here (CHAP15\AUTOCLI) will work with the dispinterface of any of the Beeper object variations in Chapter 14. The only parts that AutoCli does not exercise are the custom portion of the dual interface of Beeper4 and the IProvideClassInfo implementation of Beeper5. In any case, be sure to create the proper registry entries for each Beeper object using the REG files included with each of those samples before attempting to run AutoCli with them.

For whatever Beeper variation is used, AutoCli displays the same menu commands as shown in Figure 15-1. These commands allow you to get the value of the Sound property, set that property to its legal values, set Sound to a bogus value to generate an exception, and call the object's Beep method. AutoCli also displays the return value of a property get or a call to Beep in its client area as well as any error codes that come back, such as DISP_E_EXCEPTION.

Figure 15-1.

AutoCli and its menu structure.


MFC's COleDispatchDriver

One thing you will notice in this section is that it takes considerable C or C++ code to make any call or to access a property through IDispatch::Invoke. Tools such as Visual Basic hide much of the complexity by providing a simpler language structure that translates into IDispatch calls. For controllers written in C++, the Microsoft Foundation Classes provide a class called COleDispatchDriver that makes IDispatch calls just as easy. Instead of having to fill all the structures to call IDispatch::Invoke yourself, you can pass arguments to members of this class on the stack. In other words, COleDispatchDriver can make calling members of a dispinterface as simple as calling members of a custom interface, where MFC does the dirty work of filling all the structures required by Invoke.