Events in win32com

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


"Mark Hammond" <MarkH at ActiveState.com> wrote in message
news:3A418D02.2040302 at ActiveState.com...
> 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):
    try:
        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")
ie.Navigate('c:/index.htm')
ie.Visible=1

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:
    pythoncom.PumpWaitingMessages()


What I see on the output:

D:\PySym>python tev1.py
<module 'win32com.gen_py.3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0' from
'd:\py
thon20\win32com\gen_py\3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0\__init__.p
yc'>

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


and indeed, the generated directory:

D:\Python20\win32com\gen_py\3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0

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

Reading the CLSIDToPackageMap in __init__.py, 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 HTMLDocumentEvents2.py
gets built in the bForDemand setting...?  Is there a canonical/
recommended way...?

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

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


Alex






More information about the Python-list mailing list