ComHelper

COM and ACTIVEX Programming made easier in HotBasic

Part VI – Using COM events

General Summary

Part I – Getting started

Part II – Using ComHelper

Part III – Using a helper file with the Use Invoke option

Part IV – Using a helper file without the Use Invoke option

Part V – Using an ActiveX helper file

Part VI – Using COM events

 

COM events

A feature of some COM objects is that they trigger events to signal that something has happened. This is very similar to the events generated by form objects in HotBasic. Typical events can be mouse events (onMousedown, onMousemove, etc.) or keyboard events (onkeydown, onkeypress). Other events are related to the object’s function. For instance, a web browser object will trigger an event whenever it finishes loading a page.

Many ActiveX objects support events. Some other objects do too. Note that the standard HotBasic events DON'T apply to COM and ActiveX objects. Their events are handled differently, so you only have access to those defined in the ComHelper .inc files.

COM events with ComHelper

ComHelper generates convenient templates so that you can handle COM and ActiveX events. You register events by calling SetEvent and giving a pointer to a sub you define.

Example:

declare sub KeyPressSub STD (vw_KeyAscii as variant)

create f as form
    create s as ACTIVEX
        CreateActiveX("Microsoft.Calendar")
        SetEvent(-603, codeptr(KeyPressSub)) '-603 is the code of the KeyPress event
    end create
end create

sub KeyPressSub
...
end sub

Please take note of the following points about the subs that handle COM and ActiveX events.
  1. those subs must be STD.
  2. you register them by linking them to an event code (-603 in the example above).
  3. you must refer to them using codeptr().
  4 . All their parameters are VARIANT.
  5 . the 5th difference is important: check carefully that your sub is declared with the right argument number. Unlike what happens for ordinary Hotbasic events, there is no syntax checking on compiling.

Now don't let this deter you: the good news is that ComHelper helps you with all that.

The helper file contains templates for all the event handling subs. In order to avoid errors, it is therefore quite advisable to cut and paste from those templates when you write your event subs. Of course, you're free to change the sub names to whatever you want. What must be kept is the structure.

Connecting to a set of events

In order to receive events, an object must be connected to a set of events, also called an “event interface” or “source interface”.

ActiveX events are automatically connected on creation. Otherwise, you must call ConnectEvents to specify the set of events you want to receive. You need to do it in 3 cases:

1-       for an object that is not an ActiveX object,

2-       or if you want to connect to another set of events than the initial one,

3-       (more exotic) or if the object is ActiveX but doesn’t seem to respond. Exceptionally, it might happen that on creation, the object connects to another set of events than the default one indicated by ComHelper. If it happens to you, try using ConnectEvents explicitly.

Here is an example with an IHTMLElement object. This object is not ActiveX. It is used to access an element on an HTML page, such as an image, a button, etc.

Dim elem as INTERFACE 'IHTMLElement
... <code to access the desired element on the HTML page>
elem.DisconnectEvents 'disconnect previously connected events if any.
elem.ConnectEvents("{3050F33C-98B5-11CF-BB82-00AA00BDCE0B}") 'connect to the HTMLElementEvents set

Alternately, you can do:

elem.DisconnectEvents 'disconnect previously connected events if any.
elem.ConnectEvents("") 'empty string -> connect to the default events for that object

Alter the call to ConnectEvents, you can register event handlers by using SetEvent.

Nota: connecting a same object to different event sets.
The COM specification seems to forbid it. However, it is possible with ComHelper. Personally, I can see no harm, provided you’re sure that the different sets of events do not use the same event codes.

Generating event templates

There are 2 ways to generate event templates in ComHelper.

1-       If you check an object and this object has default events, then the event templates will be generated automatically in the ComHelper file.

2-       Otherwise, check the corresponding box in the “Event interfaces” grid.

 

Conclusion

Give it a try!

Also, don't be shy. ComHelper is there for you to tweak and play with. Don't hesitate to go under the hood and see how things are done. As you get more understanding of the simple cases, then you'll be able to proceed to more complex objects, and event push the envelope: fixing the code when ComHelper reaches its limits.

And remember: when you feel you're stuck, the internet is an invaluable source of code snippets and documentation to tap from.