[python-win32] MSHTML wrapper class and example using IWebBrowser2

Luke Kenneth Casson Leighton lkcl at lkcl.net
Thu Aug 6 22:35:12 CEST 2009


would you believe it - XMLHttpRequest needs that third version, the
one where you have to set up a VARIANT which contains a pointer to a
COM object with an IDispatch interface :)

ughhh.  this is the one where, inside the Dispatch Invoke callback,
the args received when the event (onreadystatechange in this case)
fires do _not_ contain the event itself.  fortunately, in the case of
XMLHttpRequest handling, you don't actually care about the event, you
only care that it happened.  as long as the original COM object python
class instance has a pointer to the original XMLHttpRequest object,
you can start doing checks for readyState, get the responseText,
responseXML etc. etc.

so - mshtmlevents is a botched-up version of comtypes.events from
several years ago.  this time, i didn't bother using
GetDispEventsReceiver i just threw together an _DispEventReceiver()
and set the dispmap manually, given that the XMLHttpRequest is going
to call its IDispatch Invoke method with 0.


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

        rcvr = mshtmlevents._DispEventReceiver()
        rcvr.dispmap = {0: event_fn}

        rcvr.sender = node
        ifc = rcvr.QueryInterface(IDispatch)
        v = VARIANT(ifc)
        setattr(node, event_name, v) # node is the XMLHttpRequest COM object
        return ifc

to actually create the XMLHttpRequest, you do this:

from comtypes.client.dynamic import Dispatch

    def getXmlHttpRequest(self):
        print "getXMLHttpRequest"
        o = comtypes.client.CreateObject('MSXML2.XMLHTTP.3.0')
        print "getXMLHttpRequest", o
        return Dispatch(o)

that's it!  now you have an XMLHttpRequest object - in python - you
can set up a python callback, and you're away.

i'm just really surprised that this has been, apart from the voodoo
magic incantations, pretty straightforward.  the only bugbear is that
the MSHTML COM interfaces are just as usly as.. well... IE6 :)  so,
ironically, it's going to be necessary to examine pyjamas's IE6
support (overrides) to see what needs to be done in python!

event.returnValue = True;

instead of event.preventDefault() etc. etc. argh....


More information about the python-win32 mailing list