[python-win32] DispatchWithEvents design question

Richard Bell rbell01824 at earthlink.net
Wed Jun 6 14:03:27 CEST 2007


Thanks Tim and Mark.  I appreciate your help.  BTW Mark, I'm the same
Richard Bell you helped in this area about a year ago and worked on the IE
examples in the current distribution.  

Tim Roberts wrote
|Yes, that's right.  I didn't see your earlier post.  When did you send
|that?

It was sent on June 5th.  I didn't get any feedback so I really don't know
why it works as it does and that concerns me as it seems, based on my rather
doubtful understanding of COM, that it shouldn't work at all.  If anyone has
a clue/guess I'd appreciate it.  I've included some more complete example
code below that also illustrates the affair.

Mark Wrote
|You may actually find that this is not necessary if your main Python thread
|is running a message loop.  These message loops are tricky, and used
|primarily as a way to "marshal" calls to an appropriate thread - eg, the IE
|event probably comes in on a different thread - that thread posts a message
|to the main thread, which is expected to run its loop so the correct magic
|will happen.  Thus, the behaviour of and requirement for message loops
|depends on the object being used, and also the COM threading model of the
|thread using the object.

I should have been clearer in my original post that I'm running in an
early-binding apartment-threaded model.

|> But I'm a bit concerned
|> that the new IE
|> may start generating events BEFORE I return from the original IE's
|> NewWindow3 event routine!
|
|That shouldn't be possible until the message loop is established (assuming
|these events are being delivered via the message loop)

This is the crux of my concern.  I've noticed the following
- in an apartment threaded model
- create an event class and provide event routines for OnVisible and
OnCommandStateChange that simply print a notice of the event
- start an IE with DispatchWithEvents
- navigate to some page
- the event routines for OnVisible and OnCommandStateChange BOTH RUN even if
there is NO message pump!

Here is some example code:

--- code ---
# test events WITHOUT a message pump
import win32com.client

class events():
    def OnVisible(self, vis):
        print 'OnVisible is:', vis
    def OnBeforeNavigate2(self,pDisp,url,flags,
                          targetFrameName,postData,
                          headers,cancel):
        print "OnBeforeNavigate2 on url [%s] on frame [%s]"% \
              (url,targetFrameName)
    def OnCommandStateChange(self,
                             Command,
                             Enable):
        print 'OnCommandStateChange: %s %s'%(Command,Enable)

ie = win32com.client.DispatchWithEvents(
    'InternetExplorer.Application',
    events)
# NO PUMP MESSAGE
ie.Visible = 1
ie.Navigate('www.google.com')
--- end code ---

And here is the output I get
--- output ---
OnVisible is: True
OnCommandStateChange: 2 False
OnBeforeNavigate2 on url [http://www.google.com/] on frame []
OnCommandStateChange: 1 False
--- end output ---

In this example there is no message pump that I'm aware of yet the event
routines clearly execute.  What's going on?

In a possibly related matter, I've noticed that under some non-reproducible
circumstances it is possible to get a couple of events from IE BEFORE the
return from DispatchWithEvents (when there shouldn't be any messages being
pumped)!  What I suspect may be occurring is that when IE is started via
DispatchWithEvents it starts navigating to its home page.  Perhaps that
navigation generates events that can occur while DispatchWithEvents is still
getting itself organized.  How they get passed through to the Python
On-event routines is not clear to me.

For whatever its worth, I'll gladly contribute another example for the
distribution once I've sorted through these questions.

Thanks again for your feedback and help.  I really appreciate it.

Regards,
Richard



More information about the Python-win32 mailing list