COM Events


COM events


The Tcl Windows API
a Tcl extension to provide connectivity to the resident host's component model
a COM client and server


A "COM type library" defines COM events--roughly. Chin Huang writes, "If the application provides a type library, the class declaration for the application object may list them. For example, let's examine the type library for Internet Explorer using the type library viewer in OLE View ["OLE Object Viewer"]. Select menu item File -> View TypeLib... In the Open dialog, select the file SHDOCVW.DLL in the %WINDIR%\system32 directory.

The class declaration for the Internet Explorer application is

coclass InternetExplorer {
    [default] interface IWebBrowser2;
    interface IWebBrowserApp;
    [default, source] dispinterface DWebBrowserEvents2;
    [source] dispinterface DWebBrowserEvents;

The source attribute marks interfaces that an object must implement in order to receive events from the application. The interface marked [default, source] indicates an interface that an event listener would choose by default. Each interface has an interface identifier (IID). This is the IID refered to in the tcom manual .

Each source interface declares a set of methods. Each method corresponds to an event. To fire an event, the application invokes the corresponding method on the listener object.

So getting the class declaration is key to finding the events an application can send. If you're lucky, the application may implement the IProvideClassInfo interface, which provides exactly this information."


tcom usage with IE:

package require tcom

proc sink {eventName args} {
    puts "$eventName $args"

set application_name InternetExplorer.Application
if {[catch {
    set application [::tcom::ref getactiveobject $application_name]
}]} {
    set application [::tcom::ref createobject $application_name]
::tcom::bind $application sink
$application Visible 1
vwait forever

As one uses IE, a process executing this script churns out lots of reports:

OnVisible 1
StatusTextChange Done
StatusTextChange Done
CommandStateChange -1 0
CommandStateChange -1 0
StatusTextChange Done
ProgressChange 100 10000
PropertyChange {{265b75c0-4158-11d0-90f6-00c04fd497ea}}
PropertyChange {{265b75c1-4158-11d0-90f6-00c04fd497ea}}
PropertyChange {{118D6040-8494-11d2-BBFE-0060977B464C}}
PropertyChange {{04AED800-8494-11d2-BBFE-0060977B464C}}
StatusTextChange {}
StatusTextChange {}
StatusTextChange {}
NavigateComplete2 ::tcom::handle0x008AF518 http://PAGE3
StatusTextChange Done
ProgressChange 10000 10000
ProgressChange -1 10000
TitleChange {TITLE3}
StatusTextChange {HEAD3}
ProgressChange 10000 10000
DocumentComplete ::tcom::handle0x008CE880 http://PAGE3

Note that, while IE is a good application for this sort of demonstration, with an interesting object model, it also presents several problems. One, apparently, is that other applications share object models with it, and this demonstration appears to behave erratically when other applications are open. There's probably a more complete and succinct description of the behavior. For a start, though, run the script with only the Tcl instance and IE active.

To qualify the binding, something like

tcom::import "$env(WINDIR)/system32/SHDocVw.dll"
set browserEvents [::tcom::info interface ::SHDocVw::DWebBrowserEvents2]
set iid [$browserEvents iid]
# [$browserEvents methods] shows eventNames, among other things.
tcom::bind $application sink $iid

is necessary.

See Also

Handling WMI events using TWAPI
examples of COM event handling with TWAPI