return code from win32event.WaitForMultipleObjects()

Mark Hammond mhammond at skippinet.com.au
Tue May 21 02:56:18 EDT 2002


Miranda Evans wrote:
> I do not understand why win32event.WaitForMultipleObjects is returning
> the values that it is returning in this example.
> 
> Using one of the events from testMSOfficeEvents.py as the basis for
> this
> test, I created test_demo.py.  Using python 2.2; O/S is Windows 2000;
> using PythonWin.
> 
> contents of test_demo.py are:

This doesn't work as shown:

>       rc = win32event.WaitForMultipleObjects((g.event,),
>            0, 1000, win32event.QS_ALLEVENTS)

This should be MsgWaitForMultipleObjects.

> Since the message 'double click happened' appears, I'm assuming that
> the code in the OnSheetBeforeDoubleClick() method got executed, and
> I'm assuming that the following statement in the
> OnSheetBeforeDoubleClick() method:
> 
> win32event.SetEvent(self.event)
> 
> got executed.  

This is a bad assumption :(  Adding a print statement at the *end* of 
the method shows it is not reached.

It turns out that there is a bug in the COM support, in that any 
exceptions in event handlers are silently eaten.  If you add a:
   try:
     whatever..
   except:
     traceback.print_exc()

You will see that the specific exception is that "self.event" does not 
exist.

This implies that self.__init__ was not called.  Again, we have a COM 
support bug :( - __init__ for user classes was never called - I have 
fixed that here and will be in the next version.  So, the work around is 
to specifically set "xl.event" in the mainline code.

But, even then, it turns out we have a different problem again.  Note 
the lines:

    g = xlEv()
    xl=win32com.client.DispatchWithEvents("Excel.Application", xlEv)

*both* of these lines create an xlEv() class.  Hence, "g" is one 
instance, but "xl" is another instance on which the actual events fire. 
  Hence, g.event will never be set, but xl.event will.

Below is a complete version that works:

import time, win32event, win32com.client, pythoncom
class xlEv:
    def OnSheetBeforeDoubleClick(self, sh, target, cancel):
       win32event.SetEvent(self.event)

def demo():
    xl=win32com.client.DispatchWithEvents("Excel.Application", xlEv)
    xl.event = win32event.CreateEvent(None, 0, 0, None) # work around
    xl.Visible=1
    xl.Workbooks.Add()
    start_time = time.time()
    while 1:
       rc = win32event.MsgWaitForMultipleObjects((xl.event,),
            0, 1000, win32event.QS_ALLEVENTS)
       if rc == win32event.WAIT_OBJECT_0:
          print 'event signalled'
          break
       elif rc == win32event.WAIT_OBJECT_0+1:
          pythoncom.PumpWaitingMessages()
       # check for timeout
       if time.time() - start_time > 15:
          print 'timed out'
          break

demo()

Mark.




More information about the Python-list mailing list