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.