Events in win32com
Alex Martelli
aleaxit at yahoo.com
Thu Dec 21 09:04:46 EST 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