ActiveX Widget Events
Events generated by an ActiveX control are dispatched using the standard IDL widget methodology. When an ActiveX event is passed into IDL, it is packaged in an anonymous IDL structure that contains the ActiveX event parameters.
While the actual structure of an event generated by an ActiveX control will depend on the control itself, the following gives an idea of the structure's format:
{ID : 0L,
TOP : 0L,
HANDLER : 0L,
DISPID : 0L, ; The DISPID of the callback method
EVENT_NAME : "", ; The name of the callback method
<Param1 name> : <Param1 value>,
<Param2 name> : <Param2 value>,
<ParamN name> : <ParamN value>
}
As with other IDL Widget event structures, the first three fields are standard. ID is the widget id of the widget generating the event, TOP is the widget ID of the top level widget containing ID, and HANDLER contains the widget ID of the widget associated with the handler routine.
The DISPID field contains the decimal representation of the dispatch ID (or DISPID) of the method that was called. Note that in the OLE/COM Object Viewer, this ID number is presented as a hexadecimal number. Other applications (Microsoft Visual Studio among them) may display the decimal representation.
The EVENT_NAME field contains the name of the method that was called.
The Param name fields contain the values of parameters returned by the called method. The actual parameter name or names displayed, if any, depend on the method being called by the ActiveX control.
Using the ActiveX Widget Event Structure
Since the widget event structure generated by an ActiveX control depends on the method that generated the event, it is important to check the type of event before processing values in IDL. Successfully parsing the event structure requires a detailed understanding of the dispatch interface of the ActiveX control; you must know either the DISPID or the method name of the method, and you must know the names and data types of the values returned.
For example, suppose the ActiveX control you are incorporating into your IDL application includes two methods named Method1 and Method2 in a dispatch interface that looks like this:
dispinterface MyDispInterface {
properties:
methods:
[id(0x00000270)]
void Method1([in] EventInfo* EventInfo);
[id(0x00000272)]
HRESULT Method2([out, retval] BSTR* EditData);
};
A widget event generated by a call to Method1, which has no return values, would look something like:
** Structure <3fb7288>, 5 tags, length=32, data length=32: ID LONG 13 TOP LONG 12 HANDLER LONG 12 DISPID LONG 624 EVENT_NAME STRING 'Method1'
Note that the DISPID is 624, the decimal equivalent of 270 hexadecimal.
A widget event generated by a call to Method2, which has one return value, would look something like:
** Structure <3fb7288>, 6 tags, length=32, data length=32: ID LONG 13 TOP LONG 12 HANDLER LONG 12 DISPID LONG 626 EVENT_NAME STRING 'Method2' EDITDATA STRING 'some text value'
An IDL event-handler routine could use the value of the DISPID field to check which of these two ActiveX control methods generated the event before attempting to use the value of the EDITDATA field:
PRO myRoutine_event, event IF(event.DISPID eq 626) THEN BEGIN PRINT, event.EDITDATA ENDIF ELSE BEGIN <do something else> ENDELSE END
Dynamic Elements in the ActiveX Event Structure
Parameter data included in an event structure generated by an ActiveX control can take the form of an array. If this happens, the array is placed in an IDL pointer, and the pointer, rather than the array itself, is included in the IDL event structure. Similarly, an ActiveX control may return a reference to another COM object, as described in References to Other COM Objects, in its event structure.
IDL pointers and objects created in this way are not automatically removed; it is the IDL programmer's responsibility free them using a routine such as PTR_FREE, HEAP_FREE, or OBJ_DESTROY.
If it is unclear whether the event structure will contain dynamic elements (objects or pointers) it is best to pass the ActiveX event structure to the HEAP_FREE routine when your event-handler routine has finished with the event. This will ensure that all dynamic portions of the structure are released.