7  COM classes and objects

COM classes are off-the-shelf components that you can place in your MysterX program. You use the component by calling its methods, and reading and writing its properties.

Each COM component is uniquely identified by a 128-bit entity called a CLSID. Such a component is a COM class. In most cases, you don't have to use a CLSID directly in MysterX.

On your computer, there are many COM components installed. Which components are installed depends on the version of the operating system you have, and what application software you have installed. You can obtain a list of their names with

(com-all-coclasses)

The returned list is likely to be quite long. Some components are designated ``ActiveX controls'', because they meet certain criteria for suitability as interactive controls. You can get a list of all ActiveX controls on your computer with

(com-all-controls)

Each element in the returned list is also contained in the all-com-classes list, but many COM components are not ActiveX controls.

You can place an instance of a COM class in your document in several ways. On most systems, some version of the ActiveX control ``Calendar Control'' is installed. Its exact name depends on the version. Assuming its name is ``Calendar Control 8.0'', you can use

(define cal (send doc insert-object "Calendar Control 8.0"))

to place the instance at the beginning of the document. The variable cal becomes bound to a value of type <com-object>. The method append-object places a COM object at the end of the document. There are also insert-object and append-object methods for the mx-element% class, which place COM objects before or after an individual element.

You can retrieve a list of all objects in a document with

(send doc objects)

The order of objects in the returned list is the same as the order of objects in the document.

Most COM classes support a form of reflection. That is, those classes can reveal information about themselves inside a program that uses them. That's useful, because you need to know what methods and properties a COM component has before you can use it. For instance, to get a list of the methods in the Calendar Control, run

(com-methods cal) 

which returns a list of strings. To get a list of the control's readable properties, use

(com-get-properties cal) 

To get a list of its writable properties, use

(com-set-properties cal) 

Having the names of methods and properties is not enough to use them. You also have to know what arguments methods and properties they take. Again, we can use reflection to get this information. We can get the type of a method as follows:

(com-method-type cal "NextYear")

which returns (-> void). The types of the arguments appear before the arrow, and the return type appears after it. In this case, the method takes no arguments, and returns the one Scheme value which has the type void. That means that the method is useful for whatever side effects it has, not for its trivial return value. So we can call the ``NextYear'' method with:

(com-invoke cal "NextYear")

If you've been entering the code into MzScheme, you should see the calendar date change to the next year.

Let's get the type of a property:

(com-get-property-type cal "Value")

which returns (-> mx-any). The property takes no arguments. The type mx-any means that the return type might be any value recognizable by a COM object. Let's try another property:

(com-get-property-type cal "Day")

which returns (-> short-int). Again, no arguments are required to read the property. short-int is a 16-bit integer. We can read this property with

(com-get-property cal "Day")

To get the type of a writable property, use com-set-property-type; to actually write it, use com-set-property!. The usage of these procedures is similar to that for com-get-property-type and com-get-property.