Flylib.com

Books Software

 
 
 

Properties, Methods, and Collections

Properties, Methods, and Collections

The distinction between a property and a method is somewhat artificial. Basically, a property is a value that can be both set and retrieved. You can, for example, set and get the Selection property for an Excel application. Another example is Excel's Width property, which applies to many object types. Some Excel properties are read-only; most are read/write.

Properties don't officially have parameters, but some properties are indexed . The property index acts a lot like a parameter. It doesn't have to be an integer, and it can have more than one element (row and column, for example). You'll find many indexed properties in Excel's object model, and Excel VBA can handle indexed properties in Automation components .

Methods are more flexible than properties. They can have zero or many parameters, and they can either set or retrieve object data. Most frequently they perform some action, such as showing a window. Excel's Select method is an example of an action method.

The Excel object model supports collection objects. If you use the Worksheets property of the Application object, you get back a Sheets collection object, which represents all the worksheets in the active workbook. You can use the Item property (with an integer index) to get a specific Worksheet object from a Sheets collection, or you can use an integer index directly on the collection.

The Problem That Automation Solves

You've already learned that a COM interface is the ideal way for Windows programs to communicate with one another, but you've also learned that designing your own COM interfaces is mostly impractical . Automation's general-purpose interface, IDispatch , serves the needs of both C++ and VBA programmers. As you might guess from your glimpse of Excel VBA, this interface involves objects, methods , and properties.

You can write COM interfaces that include functions with any parameter types and return values you specify. IMotion and IVisual , created in Chapter 24, are some examples. If you're going to let VBA programmers in, however, you can't be fast and loose anymore. You can solve the communication problem with one interface that has a member function smart enough to accommodate methods and properties as defined by VBA. Needless to say, IDispatch has such a function: Invoke . You use IDispatch::Invoke for COM objects that can be constructed and used in either C++ or VBA programs.

Now you're beginning to see what Automation does. It funnels all intermodule communication through the IDispatch::Invoke function. How does a client first connect to its component? Because IDispatch is merely another COM interface, all the registration logic supported by COM comes into play. Automation components can be DLLs or EXEs, and they can be accessed over a network using distributed COM (DCOM).

The IDispatch Interface

IDispatch is the heart of Automation. It's fully supported by COM marshaling (that is, Microsoft has already marshaled it for you), as are all the other standard COM interfaces, and it's supported well by the MFC library. At the component end, you need a COM class with an IDispatch interface (plus the prerequisite class factory, of course). At the client end, you use standard COM techniques to obtain an IDispatch pointer. (As you'll see, the MFC library and the wizards take care of a lot of these details for you.)

Remember that Invoke is the principal member function of IDispatch . If you looked up IDispatch::Invoke in the Visual C++ online documentation, you'd see a really ugly set of parameters. Don't worry about those now. The MFC library steps in on both sides of the Invoke call, using a data-driven scheme to call component functions based on dispatch map parameters that you define with macros.

Invoke isn't the only IDispatch member function. Another function your controller might call is GetIDsOfNames . From the VBA programmer's point of view, properties and methods have symbolic names , but C++ programmers prefer more efficient integer indexes. Invoke uses integers to specify properties and methods, so GetIDsOfNames is useful at the start of a program for converting each name to a number if you don't know the index numbers at compile time. You've already seen that IDispatch supports symbolic names for methods. In addition, the interface supports symbolic names for a method's parameters. The GetIDsOfNames function returns those parameter names along with the method name. Unfortunately, the MFC IDispatch implementation doesn't support named parameters.