In win32, as in other event-driven systems, you must process messages or bad things happen. (Or at best, good things don't happen.) The MsgWaitForMultipleObjects is one way to deal with handling messages as well as coordinating several other activities.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
import win32event import pythoncom TIMEOUT = 200 # ms StopEvent = win32event.CreateEvent(None, 0, 0, None) OtherEvent = win32event.CreateEvent(None, 0, 0, None) class myCoolApp: def OnQuit(self): win32event.SetEvent(StopEvent) # exit msg pump def _MessagePump(): while 1: rc = win32event.MsgWaitForMultipleObjects( (StopEvent,OtherEvent), 0, # wait for all = false TIMEOUT, # (or win32event.INFINITE) win32event.QS_ALLEVENTS) # type of input # You can call a function here if it doesn't take too long. # It will get executed *at least* every 200ms -- possibly # a lot more, depending on the number of windows messages received. if rc == win32event.WAIT_OBJECT_0: # Our first event listed was triggered. # Someone wants us to exit. break elif rc == win32event.WAIT_OBJECT_0+1: # Our second event "OtherEvent" listed was set. # This is from some other component - # wait on as many events as you need elif rc == win32event.WAIT_OBJECT_0+2: # A windows message is waiting - take care of it. # (Don't ask me why a WAIT_OBJECT_MSG isn't defined < WAIT_OBJECT_0) # Note: this must be done for COM and other windowsy # things to work. if pythoncom.PumpWaitingMessages(): break # wm_quit elif rc == win32event.WAIT_TIMEOUT: # Our timeout has elapsed. # Do some work here (e.g, poll something can you can't thread) # or just feel good to be alive. # Good place to call watchdog(). (Editor's note: See my "thread lifetime" recepie.) pass else: raise RuntimeError( "unexpected win32wait return value")
This is one possible message pump structure you can use in your win32 application.
Messages and other events will be dispatched as soon as they are posted, and a timeout allows you to poll other components. You may need to poll if the proper calls or event-objects are not exposed to do you bidding in your win32 event loop, as many componets insist on running on the main app's thread and cannot run on spawned threads. (Also see the related "thread lifetime mangement" on polling.)