searching around on the internet for code snippets to do event
handling on MSHTML, e.g. HTMLElement insertEvent, i find ... nothing!
everybody has been struggling literally since about 2000 when the idea
of combining python and MSHTML first really took off.

i just wanted to let people know, for those doing google searches - i
did it!  i _actually_ managed to come up with the right voodoo magic
incantations where you can pass in a python callback function into
HTMLElement insertEvent.

the key was combining ctypes pointer to a comtypes.automation.VARIANT
with a python COM object with an IDispatch interface on it, which is
what you're _supposed_ to do, but it's tricky as hell to work out.

what i had to do was take a _much_ older version of
comtypes.client._events.py and hack it into submission:
http://pyjamas.svn.sourceforge.net/viewvc/pyjamas/trunk/pyjd/mshtmlevents.py

there are two styles that you can use:


    def addEventListener(self, node, event_name, event_fn):

        rcvr = mshtmlevents.GetDispEventReceiver(MSHTML.HTMLElementEvents2,
event_fn, "on%s" % event_name)
        rcvr.sender = node
        ifc = rcvr.QueryInterface(IDispatch)
        node.attachEvent("on%s" % event_name, ifc)
        return ifc


    def _addWindowEventListener(self, event_name, event_fn):

        print "_addWindowEventListener", event_name, event_fn
        #rcvr = mshtmlevents.GetDispEventReceiver(MSHTML.HTMLWindowEvents,
        #                   event_fn, "on%s" % event_name)
        #print rcvr
        #rcvr.sender = self.getGdomWindow()
        #print rcvr.sender
        #ifc = rcvr.QueryInterface(IDispatch)
        #print ifc
        #v = VARIANT(ifc)
        #print v
        #setattr(self.getGdomWindow(), "on%s" % event_name, v)
        #return ifc

self.getGdomWindow just returns the parentWindow object.

but... this second style, when the COM object created by
GetDispEventReceiver's IDispatch_Invoke function is called, you _do
not_ receive the actual IHTMLEventObj back!

so - don't use that style :)  it works, but it's useless.

i wasted 3 hours last night finding that out.  but - i'm including it
here simply for completeness.

use the first style, instead: attachEvent.  then you end up with the
MSHTML event handling system doing an Invoke on you whilst also
passing the IHTMLEventObj to you in the arguments - hooray!

so you can get event.type, event.target etc. etc.

btw please don't be confused by me attempting to do event handling on
window, in the commented-out code, i'm still struggling to get window
event handling working, but HTMLElement it actually works.

one thing that's important to note is that the MSHTML event dispatch
system will only pass 0 as the method number, NOT i repeat NOT a whole
range of numbers representing different event types.

the hacked-together code in mshtmlevents.py looks very similar to
GetEvents, which was designed to get multiple events and to cope with
multiple callbacks onto one COM object - but this is _completely_
different.  attachEvent expects a COM Object with an _exclusive_
purpose in mind.

l.
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to