Events in win32com

Alex Martelli aleaxit at
Thu Dec 21 15:04:46 CET 2000

"Mark Hammond" <MarkH at> wrote in message
news:3A418D02.2040302 at
> Paul Moore wrote:
> > Is it possible to do anything like this in Python? If not, can I do
> > the same thing another way? (I have created ie via
> > DispatchWithEvents(), but the HTML document is a property of this. Can
> > I rewrap it somehow, say as
> >   doc = DispatchWithEvents(ie.document, DocEvents)
> This is (should be) as simple as instantiating a sub-class of the makepy
> generated event class, and passing the document.

Yes, but -- how does this play with the bForDemand flag, which
is really a must when the module is as huge as MSHTML...?

> eg, something like:
> mod = EnsureModule(...)
> class MyEvents(mod.IDocumentEvents):
>    # your methods here....
> handler = MyEvents(ie.document)
> # handler should start recieving events.

Sure, once I managed to somehow grab the right module it's very
easy; but I think I've not yet grasped how to do that grabbing
in the current 'bForDemand' architecture (indispensable for
really huge type libraries, of course).  For example, consider
the following attempt:

import win32com.client, win32com.client.gencache, pythoncom

def EnsureModuleForTypelibOfObject(obj, bForDemand=1):
        ti = obj._oleobj_.GetTypeInfo()
        clsid = ti.GetTypeAttr()[0]
        tlb, index = ti.GetContainingTypeLib()
        tla = tlb.GetLibAttr()
        return win32com.client.gencache.EnsureModule(
            tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
    except pythoncom.com_error:
            raise TypeError, "This COM object can not automate the makepy
process - please run makepy manually for this object"

ie = win32com.client.gencache.EnsureDispatch("InternetExplorer.Application")

html_module = EnsureModuleForTypelibOfObject(ie.Document)

print html_module

class Handler(html_module.HTMLDocumentEvents2):
    def __init__(self, obj):
        self.seen = 0
        html_module.HTMLDocumentEvents2.__init__(self, obj)
    def Ononclick(self, *args):
        print "clic!", args
        self.seen += 1

h = Handler(doc)

while h.seen < 5:

What I see on the output:

<module 'win32com.gen_py.3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0' from

Traceback (most recent call last):
  File "", line 22, in ?
    class Handler(html_module.HTMLDocumentEvents2):
AttributeError: HTMLDocumentEvents2

and indeed, the generated directory:


only contains files named __init__ and DispHTMLDocument (.py and .pyc
for each, of course).

Reading the CLSIDToPackageMap in, I can see among
the many, many other lines, the relevant one:

 '{3050F613-98B5-11CF-BB82-00AA00BDCE0B}' : 'HTMLDocumentEvents2'

But how do I instantiate and call genpy.Generator, or arrange for
it to be instantiated and called, to ensure the
gets built in the bForDemand setting...?  Is there a canonical/
recommended way...?

I can get the file _built_ by faking, once, a
which I'm sure is not the 'clean' way, but that doesn't insert
HTMLDocumentEvents2 into the html_module's object directory,

So, what *is* the beautiful way I'm still missing after all
of my study of sources...?  Pretty please...?


More information about the Python-list mailing list