From rbell01824 at earthlink.net Fri Jun 1 15:11:33 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Fri, 1 Jun 2007 08:11:33 -0500 Subject: [python-win32] DispatchWithEvents experiment with subclass event routine and pump messages In-Reply-To: <465E10B7.70207@probo.com> References: <008c01c7a1eb$eb3f5010$6701a8c0@rjbmain><041d01c7a1ee$be0c8b50$1f0a0a0a@enfoldsystems.local> <009601c7a1ff$0dcefd70$6701a8c0@rjbmain><005d01c7a309$42a85630$6701a8c0@rjbmain> <465E10B7.70207@probo.com> Message-ID: <001b01c7a44e$64961430$6701a8c0@rjbmain> This group has been very helpful as I've worked on an IE automation class (yes I know about Pamie). I recently encountered a design issue concerning how to allow users to 'hook' event routines in the IE automation class. After a bit of thought and scratching around I decided to look into a user derived event class and ran the following experiment: >>> import win32com.client >>> class IEEvents1: ... def OnVisible(self, visible): ... print 'Visible changed:', visible ... >>> ie = win32com.client.DispatchWithEvents( 'InternetExplorer.Application', IEEvents1) >>> ie.Visible = 1 Visible changed: True >>> ie.Navigate('www.google.com') >>> Then I subclassed the event routine and played some more: >>> class IEEvents2(IEEvents1): ... def OnDocumentComplete(self, pDisp, url): ... print 'Top %s pDisp %s url %s'% \ ... (pDisp==self,pDisp,url) ... >>> ie2 = win32com.client.DispatchWithEvents( 'InternetExplorer.Application', IEEvents2) >>> ie2.Visible = 1 Visible changed: True >>> ie2.Navigate('www.citizensbank.com') >>> Top False pDisp url http://www.citizensbank.com/scripts/tc/logging.html Top False pDisp url http://www.citizensbank.com/olblogin/olblogin.aspx?f=p7X03No2hg Top True pDisp url http://www.citizensbank.com/home/ I see both the Visible event from IEEvents1 AND the DocumentComplete event from IEEvents2. So subclassing apparently works and the issue of user hooks into the event interface is resolved rather neatly via classes. That's cool but ... Who/what ran the message pump during the experiment or do I not really understand the message pump? Anyone have any insight? Regards, Richard From richard_gordon at verizon.net Sat Jun 2 21:09:39 2007 From: richard_gordon at verizon.net (Richard Gordon) Date: Sat, 02 Jun 2007 15:09:39 -0400 Subject: [python-win32] Need help with win32 com_error 'Exception occurred' Message-ID: <02e801c7a549$9360d1a0$4101a8c0@WEHEHNOTEBOOK> I've got a fatal bug using Parente's pyTTS with Python 2.3 on Windoze 32 using MS SAPI 5.1 and Hammond's win32 module. The test program is import pyTTS tts = pyTTS.Create() tts.Speak('Hello world.') The resulting debug trace is: PythonWin 2.3.5 (#62, Feb 8 2005, 16:23:02) [MSC v.1200 32 bit (Intel)] on win32. Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin' for further copyright information. Traceback (most recent call last): File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 307, in RunScript debugger.run(codeObject, __main__.__dict__, start_stepping=0) File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\debugger\__init__.py", line 60, in run _GetCurrentDebugger().run(cmd, globals,locals, start_stepping) File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\debugger\debugger.py", line 631, in run exec cmd in globals, locals File "C:\yakitome\test\examples\ex1.py", line 4, in ? tts.Speak('Hello world.') File "C:\PROGRA~1\Python23\Lib\site-packages\pyTTS\sapi.py", line 213, in Speak self.speech.Speak(text, flagsum) File "C:\Program Files\Python23\lib\site-packages\win32com\gen_py\C866CA3A-32F7-11D2-9602-00C04F8EE628x0x5x0.py", line 2637, in Speak , Flags) com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147201015), None) >>> Can anyone out there shed some light on this issue? The system does not have a sound card --- could that be the problem? My head is about to explode trying to solve this, so your help and suggestions will be much appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-win32/attachments/20070602/a0f0f7b7/attachment.html From fuzzyman at voidspace.org.uk Sun Jun 3 23:59:10 2007 From: fuzzyman at voidspace.org.uk (Michael Foord) Date: Sun, 03 Jun 2007 22:59:10 +0100 Subject: [python-win32] Interacting with Excel (IronPython) Message-ID: <466339AE.2020102@voidspace.org.uk> Hello all, I realise this is slightly off-topic as it is about IronPython rather than pywin32, but Christian Muirhead has posted an *extremely* good article about interacting with Excel to the IronPython cookbook: http://www.ironpython.info/index.php/Interacting_with_Excel As this is a topic which comes up from time to time on this list, I thought it might be of interest. The article covers the basics of interacting with spreadsheets, including registering for events (which is pretty non-intuitive without the info in his entry). There are various other entries that may be of interest (Direct3D, working with IIS, connecting to active directory, using various framework classes like FileSystemWatcher and so on). http://www.ironpython.info/index.php/Contents All the best, Michael Foord http://www.voidspace.org.uk/ironpython/index.shtml From bijanb at slac.stanford.edu Mon Jun 4 03:58:57 2007 From: bijanb at slac.stanford.edu (Bijan Berenji) Date: Sun, 3 Jun 2007 18:58:57 -0700 Subject: [python-win32] Python-win32 In-Reply-To: References: Message-ID: <90D76934-A04A-40D6-951F-74D8585C53DF@slac.stanford.edu> Hi, I have a question about xml.dom.minidom module. Suppose I have a node n. When I try >>> n.toprettyxml(" ") I get the warning: AttributeError: Node instance has no instance 'nodeType'. I am using python 2.4.4 on WinXP. Any help is appreciated. -Bijan On Jun 3, 2007, at 3:00 AM, python-win32-request at python.org wrote: > Send Python-win32 mailing list submissions to > python-win32 at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.python.org/mailman/listinfo/python-win32 > or, via email, send a message with subject or body 'help' to > python-win32-request at python.org > > You can reach the person managing the list at > python-win32-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Python-win32 digest..." > > > Today's Topics: > > 1. Need help with win32 com_error 'Exception occurred' > (Richard Gordon) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 02 Jun 2007 15:09:39 -0400 > From: "Richard Gordon" > Subject: [python-win32] Need help with win32 com_error 'Exception > occurred' > To: > Message-ID: <02e801c7a549$9360d1a0$4101a8c0 at WEHEHNOTEBOOK> > Content-Type: text/plain; charset="iso-8859-1" > > I've got a fatal bug using Parente's pyTTS with Python 2.3 on > Windoze 32 using MS SAPI 5.1 and Hammond's win32 module. The test > program is > import pyTTS > tts = pyTTS.Create() > tts.Speak('Hello world.') > > The resulting debug trace is: > > PythonWin 2.3.5 (#62, Feb 8 2005, 16:23:02) [MSC v.1200 32 bit > (Intel)] on win32. > Portions Copyright 1994-2006 Mark Hammond - see 'Help/About > PythonWin' for further copyright information. > Traceback (most recent call last): > File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin > \framework\scriptutils.py", line 307, in RunScript > debugger.run(codeObject, __main__.__dict__, start_stepping=0) > File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin > \debugger\__init__.py", line 60, in run > _GetCurrentDebugger().run(cmd, globals,locals, start_stepping) > File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin > \debugger\debugger.py", line 631, in run > exec cmd in globals, locals > File "C:\yakitome\test\examples\ex1.py", line 4, in ? > tts.Speak('Hello world.') > File "C:\PROGRA~1\Python23\Lib\site-packages\pyTTS\sapi.py", > line 213, in Speak > self.speech.Speak(text, flagsum) > File "C:\Program Files\Python23\lib\site-packages\win32com > \gen_py\C866CA3A-32F7-11D2-9602-00C04F8EE628x0x5x0.py", line 2637, > in Speak > , Flags) > com_error: (-2147352567, 'Exception occurred.', (0, None, None, > None, 0, -2147201015), None) >>>> > Can anyone out there shed some light on this issue? > > The system does not have a sound card --- could that be the problem? > > My head is about to explode trying to solve this, so your help and > suggestions will be much appreciated. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: http://mail.python.org/pipermail/python-win32/attachments/ > 20070602/a0f0f7b7/attachment.htm > > ------------------------------ > > _______________________________________________ > Python-win32 mailing list > Python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > > > End of Python-win32 Digest, Vol 51, Issue 3 > ******************************************* Bijan Berenji Applied Physics PhD candidate, Stanford University Research Assistant, Stanford Linear Accelerator Center -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-win32/attachments/20070603/f46eb6e1/attachment.html From mail at timgolden.me.uk Mon Jun 4 09:39:35 2007 From: mail at timgolden.me.uk (Tim Golden) Date: Mon, 04 Jun 2007 08:39:35 +0100 Subject: [python-win32] Interacting with Excel (IronPython) In-Reply-To: <466339AE.2020102@voidspace.org.uk> References: <466339AE.2020102@voidspace.org.uk> Message-ID: <4663C1B7.3000306@timgolden.me.uk> Michael Foord wrote: > Hello all, > > I realise this is slightly off-topic as it is about IronPython rather > than pywin32, but Christian Muirhead has posted an *extremely* good > article about interacting with Excel to the IronPython cookbook: > > http://www.ironpython.info/index.php/Interacting_with_Excel > > As this is a topic which comes up from time to time on this list, I > thought it might be of interest. The article covers the basics of > interacting with spreadsheets, including registering for events (which > is pretty non-intuitive without the info in his entry). > > There are various other entries that may be of interest (Direct3D, > working with IIS, connecting to active directory, using various > framework classes like FileSystemWatcher and so on). > > http://www.ironpython.info/index.php/Contents Looks very useful indeed, Michael. I really must find the time (and motivation) to look into IronPython. So many things to look at... so little time! TJG From grickert at coldstorage.com Mon Jun 4 14:40:20 2007 From: grickert at coldstorage.com (Gerrat Rickert) Date: Mon, 4 Jun 2007 08:40:20 -0400 Subject: [python-win32] Need help with win32 com_error 'Exception occurred' In-Reply-To: <02e801c7a549$9360d1a0$4101a8c0@WEHEHNOTEBOOK> Message-ID: ...I can't tell you the underlying *reason* it doesn't work, only that it doesn't appear to work without a sound card. ...I was probably in the same boat as you, where the machine you're developing on may not be the same as the machines this will eventualy run on. Gerrat ________________________________ I've got a fatal bug using Parente's pyTTS with Python 2.3 on Windoze 32 using MS SAPI 5.1 and Hammond's win32 module. The test program is import pyTTS tts = pyTTS.Create() tts.Speak('Hello world.') The resulting debug trace is: PythonWin 2.3.5 (#62, Feb 8 2005, 16:23:02) [MSC v.1200 32 bit (Intel)] on win32. Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin' for further copyright information. Traceback (most recent call last): File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\framework\script utils.py", line 307, in RunScript debugger.run(codeObject, __main__.__dict__, start_stepping=0) File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\debugger\__init_ _.py", line 60, in run _GetCurrentDebugger().run(cmd, globals,locals, start_stepping) File "C:\PROGRA~1\Python23\Lib\site-packages\pythonwin\pywin\debugger\debugge r.py", line 631, in run exec cmd in globals, locals File "C:\yakitome\test\examples\ex1.py", line 4, in ? tts.Speak('Hello world.') File "C:\PROGRA~1\Python23\Lib\site-packages\pyTTS\sapi.py", line 213, in Speak self.speech.Speak(text, flagsum) File "C:\Program Files\Python23\lib\site-packages\win32com\gen_py\C866CA3A-32F7-11D2-9602 -00C04F8EE628x0x5x0.py", line 2637, in Speak , Flags) com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147201015), None) >>> Can anyone out there shed some light on this issue? The system does not have a sound card --- could that be the problem? My head is about to explode trying to solve this, so your help and suggestions will be much appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-win32/attachments/20070604/a6826d7f/attachment.html From rbell01824 at earthlink.net Tue Jun 5 19:38:36 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Tue, 5 Jun 2007 12:38:36 -0500 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <001b01c7a44e$64961430$6701a8c0@rjbmain> References: <008c01c7a1eb$eb3f5010$6701a8c0@rjbmain><041d01c7a1ee$be0c8b50$1f0a0a0a@enfoldsystems.local> <009601c7a1ff$0dcefd70$6701a8c0@rjbmain><005d01c7a309$42a85630$6701a8c0@rjbmain><465E10B7.70207@probo.com> <001b01c7a44e$64961430$6701a8c0@rjbmain> Message-ID: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> I'm continuing to work on a class to automate IE in an apartment-threaded early binding class. The current design is relatively conventional and looks like this: class Yie(object): def __init__(self, eventClass): --- code deleted --- self._ie = win32com.client.DispatchWithEvents( "InternetExplorer.Application", YieEvents) self._ie.Visible = 1 _yamies[self._ie.HWND] = self --- code deleted --- --- class methods that automate IE --- class YieEvents(object): --- class methods that respond to IE events --- It is necessary for several reasons for the event class event handlers to occasionally reference attributes and methods in the Yie instance holding self._ie. To support this requirement I keep a dictionary of Yie instances indexed by self._ie.HWND which is known to self._ie and its YieEvents On-event handlers. But there is a catch. When DispatchWithEvents creates self._ie it first initializes the IE com object, then an internal object, and finally YieEvents. Depending on timing, it is possible for IE to start throwing events BEFORE control returns to the Yie's __init__ routine and BEFORE _yamies is set. When this occurs the event routines are unable to find the Yie instance they are servicing. As a purely practical matter, this doesn't really cause much difficulty because the early events are OnVisible and OnCommandStateChange both of which can be safely ignored as IE comes up. Even so, I'm troubled by the behavior. In casting around for a solution I poked into the code for DispatchWithEvents. If I understand it correctly, it is possible to include IE automation methods as part of the event class something like this: class Yie: --- class variables --- def __init__(self): --- instance variables --- def NavigateWait1( self, url): --- code to navigate and wait for completion --- --- methods to provide other IE automation services --- def OnVisible(self, vis): --- code to handle OnVisible event --- --- methods to handle other IE events --- Using this design it is possible to use the class something like this: ie = win32com.client.DispatchWithEvents( 'InternetExplorer.Application',Yie) ie.Visible=True ie.NavigateWait1('www.google.com') Since the revised Yie class holds BOTH the event and automation methods the need for the dictionary goes away and the On-event routines can reference whatever instance attributes/methods are needed. A bit of experimentation shows that this does indeed work (if anyone is interested, I'll gladly post the code). Question 1: Is this a good design/idea/advisable? I'm still learning about COM automation and there are many that understand it rather better than I. What do you think? One of the things that has to happen for this to work is that a navigating IE automation method (Navigate2, GoBack, etc.) MUST pump messages or IE hangs. The net of this is that the IE automation code to support navigation needs to look something like this: def NavigateWait1( self, url, timeout): startTime = time.time() self.Navigate2( url ) while True: pythoncom.PumpWaitingMessages() rc = win32event.MsgWaitForMultipleObjects( (self._eventNone,), 0, 250, win32event.QS_ALLEVENTS) if (rc == win32event.WAIT_TIMEOUT): if time.clock() - startTime >= timeout: return During navigation the while loop pumps messages every 250 MS. As events occur the event routines are invoked and do whatever they do including, possibly, changing attributes within the IE automation instance. Eventually, the timeout elapses and the while loop terminates. But ... Question 2: Is this safe? Python source gets translated into byte code. I understand that a single byte code is atomic and can not be interrupted (is this true?). But how about a statement? There are a number of places in the automation code where several statements have to execute entirely or the internal state of the automation instance is inconsistent. Do I need to protect these with a Mutex? Alternately, can I depend on pythoncom.PumpWaitingMessages to be atomic such that the event routines CAN ONLY occur while the while loop is invoking PumpWaitingMessages? One of the things the IE automation class needs to deal with is an IE NewWindow event. The nub of this is that when a page wants to generate a new window is causes an OnNewWindow3 event. The event has the following template: def OnNewWindow3(self, ppDisp=defaultNamedNotOptArg, cancel=defaultNamedNotOptArg, dwFlags=defaultNamedNotOptArg, bstrUrlContext=defaultNamedNotOptArg, bstrUrl=defaultNamedNotOptArg): The event routine can return nothing, in which case IE does whatever the browser's configuration defines. Alternately, the event routine can return True to cancel the NewWindow request (see http://msdn2.microsoft.com/en-us/library/aa768288.aspx). Finally, the event routine can return the IDispatch interface pointer of an InternetExplorer object that will host the new window. This latter bit means that the event routine must instantiate a new instance something like this: new_ie = win32com.client.DispatchWithEvents( 'InternetExplorer.Application',Yie) Based on my knowledge of Python, I think this should work just fine. It is, after all, just a method in a class creating a new instance of the class. Some experimentation shows that the OnNewWindow3 event routine can do this: new_ie = win32com.client.DispatchWithEvents( 'InternetExplorer.Application',Yie) return new_ie, false and the new IE instance is created. 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 is, after all, the problem this new design is intended to address. If it does, this means that the Python COM routines can potentially be re-entered while processing an event. Alternately, does PumpWaitingMessages insure that at most one message at a time occurs so that the NewWindow3 event routine is guaranteed to complete BEFORE another event on the original or new IE can occur? Question 3: Does PumpWaitingMessages insure that at MOST one message/event is pumped such that reentrancy is not an issue? My apologies for the length of this post but I wanted to be as clear as possible in hopes that I can get some feedback. I appreciate that these are rather subtle questions. If I'm able to satisfy myself on the answers, I'll gladly provide a demo to add to the distribution for the benefit of others. Thanks in advance for any help. Regards, Richard From timr at probo.com Tue Jun 5 22:18:29 2007 From: timr at probo.com (Tim Roberts) Date: Tue, 05 Jun 2007 13:18:29 -0700 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> References: <008c01c7a1eb$eb3f5010$6701a8c0@rjbmain><041d01c7a1ee$be0c8b50$1f0a0a0a@enfoldsystems.local> <009601c7a1ff$0dcefd70$6701a8c0@rjbmain><005d01c7a309$42a85630$6701a8c0@rjbmain><465E10B7.70207@probo.com> <001b01c7a44e$64961430$6701a8c0@rjbmain> <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> Message-ID: <4665C515.3030603@probo.com> Richard Bell wrote: > Question 3: Does PumpWaitingMessages insure that at MOST one message/event > is pumped such that reentrancy is not an issue? > I can't answer the other two questions, but I can answer this one, definitively yes. A Windows message queue is associated with a single thread only, and only that thread can dispatch the messages. It will not dispatch message #2 until message #1 has completed and returned. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From rbell01824 at earthlink.net Tue Jun 5 22:45:44 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Tue, 5 Jun 2007 15:45:44 -0500 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <4665C515.3030603@probo.com> References: <008c01c7a1eb$eb3f5010$6701a8c0@rjbmain><041d01c7a1ee$be0c8b50$1f0a0a0a@enfoldsystems.local> <009601c7a1ff$0dcefd70$6701a8c0@rjbmain><005d01c7a309$42a85630$6701a8c0@rjbmain><465E10B7.70207@probo.com> <001b01c7a44e$64961430$6701a8c0@rjbmain><000001c7a798$5bcbf7f0$6701a8c0@rjbmain> <4665C515.3030603@probo.com> Message-ID: <001e01c7a7b2$7deefca0$6701a8c0@rjbmain> Thanks Tim. If PumpWaitingMessages is queued AND messages can only occur when PumpWaitingMessages is called, then Questions 2 and 3 are resolved since absent the call to PumpWaitingMessages events can not occur. I am still a bit concerned, however, because of an experiment I ran several days ago, see "DispatchWithEvents experiment with subclass eventroutine and pump messages" from 6/5. In this experiment there were NO calls to PumpWaitingMessages yet events/messages DID occur! How sure are you? FWIW, memory serves that the OnVisible event is unique and doesn't have to be pumped. I do not remember where I read this or why it is so. Such, however, is NOT the case with OnDocumentComplete. So I'm still a bit uncertain. Do you know of any hard test to verify the behavior? Regards, Richard |Tim Roberts, timr at probo.com |Richard Bell wrote: |> Question 3: Does PumpWaitingMessages insure that at MOST one |message/event |> is pumped such that reentrancy is not an issue? |> | |I can't answer the other two questions, but I can answer this one, |definitively yes. A Windows message queue is associated with a single |thread only, and only that thread can dispatch the messages. It will |not dispatch message #2 until message #1 has completed and returned. | From mhammond at skippinet.com.au Wed Jun 6 00:54:57 2007 From: mhammond at skippinet.com.au (Mark Hammond) Date: Wed, 6 Jun 2007 08:54:57 +1000 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> Message-ID: <09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local> > In casting around for a solution I poked into the code for > DispatchWithEvents. If I understand it correctly, it is > possible to include > IE automation methods as part of the event class something like this: > > class Yie: > --- class variables --- > def __init__(self): > --- instance variables --- > def NavigateWait1( self, url): > --- code to navigate and wait for completion --- > --- methods to provide other IE automation services --- > def OnVisible(self, vis): > --- code to handle OnVisible event --- > --- methods to handle other IE events --- > > Using this design it is possible to use the class something like this: > > ie = win32com.client.DispatchWithEvents( > 'InternetExplorer.Application',Yie) > ie.Visible=True > ie.NavigateWait1('www.google.com') > > Since the revised Yie class holds BOTH the event and > automation methods the > need for the dictionary goes away and the On-event routines > can reference > whatever instance attributes/methods are needed. A bit of > experimentation > shows that this does indeed work (if anyone is interested, > I'll gladly post > the code). > > Question 1: Is this a good design/idea/advisable? Yep, that looks fine. > One of the things that has to happen for this to work is that > a navigating > IE automation method (Navigate2, GoBack, etc.) MUST pump > messages or IE > hangs. The net of this is that the IE automation code to > support navigation > needs to look something like this: > > def NavigateWait1( self, url, timeout): > startTime = time.time() > self.Navigate2( url ) > while True: > pythoncom.PumpWaitingMessages() > rc = win32event.MsgWaitForMultipleObjects( > (self._eventNone,), 0, 250, > win32event.QS_ALLEVENTS) > if (rc == win32event.WAIT_TIMEOUT): > if time.clock() - startTime >= timeout: > return 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. > Question 2: Is this safe? Python source gets translated into > byte code. I > understand that a single byte code is atomic and can not be > interrupted (is > this true?). But how about a statement? There are a number > of places in > the automation code where several statements have to execute > entirely or the > internal state of the automation instance is inconsistent. > Do I need to > protect these with a Mutex? You do not need to use a mutex to protect the integrity of the core Python data structures (eg, it should be impossible to "crash" a list-object) - however, you will need a mutex if there is a possibility 2 threads could cause an object to get in a logically inconsistent state (ie, Python will not crash, but your program may exhibit bugs if 2 threads try and append an item to a list at the same time and then check that it is the end item, for example) > Alternately, can I depend on > pythoncom.PumpWaitingMessages to be atomic such that the > event routines CAN > ONLY occur while the while loop is invoking PumpWaitingMessages? I think Tim is correct - but this is not a "rule" as such. It would probably be possible to voilate this rule if you really tried, but in the general case, if any events for a single object need a message loop, all such events will. > The event routine can return nothing, in which case IE does > whatever the > browser's configuration defines. Alternately, the event > routine can return > True to cancel the NewWindow request (see > http://msdn2.microsoft.com/en-us/library/aa768288.aspx). > Finally, the event > routine can return the IDispatch interface pointer of an > InternetExplorer > object that will host the new window. This latter bit means > that the event > routine must instantiate a new instance something like this: > > new_ie = win32com.client.DispatchWithEvents( > 'InternetExplorer.Application',Yie) > > Based on my knowledge of Python, I think this should work > just fine. It is, > after all, just a method in a class creating a new instance > of the class. > Some experimentation shows that the OnNewWindow3 event > routine can do this: > > new_ie = win32com.client.DispatchWithEvents( > 'InternetExplorer.Application',Yie) > return new_ie, false > > and the new IE instance is created. 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) > If it does, this means that the > Python COM routines > can potentially be re-entered while processing an event. In the general case, that certainly is possible - but generally your event handlers will not need to be running a message loop, just the main thread itself should be. It appears your code as posted is already reentrant - your event handler runs a short message loop - if an event was delivered in that time, I'd expect us to reenter into the new event handler. > Alternately, does > PumpWaitingMessages insure that at most one message at a time > occurs so that > the NewWindow3 event routine is guaranteed to complete BEFORE > another event > on the original or new IE can occur? PumpWaitingMessages is a "normal" Windows message loop, fetching and dispatching one message at the time. It has no COM knowledge at all (it just happens to enable COM to deliver events in some cases) > Question 3: Does PumpWaitingMessages insure that at MOST one > message/event > is pumped such that reentrancy is not an issue? It pumps one message at a time, but reentrancy is possible in the general case - eg, an event handler may change an attribute on the object, which itself may deliver a synch event. In the free-threaded case this is far more likely, but running a message loop in an event handler could also cause it. Mark From rbell01824 at earthlink.net Wed Jun 6 14:03:27 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Wed, 6 Jun 2007 07:03:27 -0500 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> <09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local> Message-ID: <003201c7a832$b24f4880$6701a8c0@rjbmain> 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 From timr at probo.com Wed Jun 6 18:41:07 2007 From: timr at probo.com (Tim Roberts) Date: Wed, 06 Jun 2007 09:41:07 -0700 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <003201c7a832$b24f4880$6701a8c0@rjbmain> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain> <09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local> <003201c7a832$b24f4880$6701a8c0@rjbmain> Message-ID: <4666E3A3.9080703@probo.com> Richard Bell wrote: > 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? > These are synchronous events. That is, these events are generated directly by the requests you made. I believe you will find that the "OnVisible" callback occurs before "ie.Visible = 1" returns. It's being handled by that same thread, which is suspended waiting for IE to finish. A message pump is only required for events that arrive asynchronously. It's still single threaded. If you're familiar with the Windows GUI, this is similar to the difference between PostMessage and SendMessage (ignoring interprocess calls for now). SendMessage calls directly into the window procedure of the target window without going through the message queue; when it returns, the message is handled. PostMessage is fire-and-forget; it will be processed later, when the message loop gets around to pulling the message. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From rbell01824 at earthlink.net Thu Jun 7 17:33:39 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Thu, 7 Jun 2007 10:33:39 -0500 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <4666E3A3.9080703@probo.com> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain><09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local><003201c7a832$b24f4880$6701a8c0@rjbmain> <4666E3A3.9080703@probo.com> Message-ID: <000001c7a919$3b61f320$6701a8c0@rjbmain> Tim Roberts wrote |These are synchronous events. That is, these events are generated |directly by the requests you made. I believe you will find that the |"OnVisible" callback occurs before "ie.Visible = 1" returns. It's being |handled by that same thread, which is suspended waiting for IE to |finish. A message pump is only required for events that arrive |asynchronously. It's still single threaded. | |If you're familiar with the Windows GUI, this is similar to the |difference between PostMessage and SendMessage (ignoring interprocess |calls for now). SendMessage calls directly into the window procedure of |the target window without going through the message queue; when it |returns, the message is handled. PostMessage is fire-and-forget; it |will be processed later, when the message loop gets around to pulling |the message. That clears up a lot. Thanks. I rewrote the test, see below. When run it behaves as you suggest (see the test output below). In particular the OnVisible event occurs synchronously before return from 'ie.Visible = 1' as you suggested. I checked StatusBar and it appears to be synchronous as well. I assume then that any events associated with setting IE's properties would also be synchronous, wouldn't they? But note that when I set StatusBar false the OnStatusBar event occurs. Then when I set StatusBar true both OnCommandStateChange and OnStatusBar events occur. I expected the OnStatusBar event but NOT the OnCommandStateChange event as later in the test (after 21.407) OnCommandStateChange behaves asynchronously. Is there some bit of behavior such that when a synchronous event occurs other queued events are also processed? About a year ago, Mark Hammond helped me in this area and memory serves that when any events are processed they are all processed. Is this true? Is this behavior a function of COM or of the Python COM interface? More generally, how do I know what COM interactions will generate synchronous events and which will cause asynchronous events? Interestingly if I comment out the code starting at line 47 (the trailing PUMP for the first navigation) I get a pythoncom error and trace like this: --- begin output --- Spin for 20 seconds pythoncom error: Python error invoking COM method. Traceback (most recent call last): File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_ return self._invoke_(dispid, lcid, wFlags, args) File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_ return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None) File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 588, in _invokeex_ return func(*args) File "C:\rbell\Bell Curve Group\IE Testing\test070607a.py", line 17, in OnCommandStateChange print 'At %6.3f OnCommandStateChange: %s %s'%(time.clock(),Command,Enable) : 'NoneType' object has no attribute 'clock' --- end output --- At that point IE is still running and as the test is coming down there appears to be a window where events start flowing into the event routines but there is not enough of the Python/test application still available to handle them. I'm not sure that this is a bug or just an unfortunate boundary condition. Based on what I think I understand about COM automation I'm inclined to think that this condition can occur on any COM interface with event support. At any event thanks again for your input. It was very helpful. FWIW, anyone looking at this code should know that it is NOT best/good/OK practice. It's just something I hacked together to explore this issue and should NOT be used as a base for anything but experimentation. --- begin code --- # test events WITHOUT a message pump import win32com.client import pythoncom import time class events(): def OnVisible(self, vis): print 'At %6.3f OnVisible is %s'%(time.clock(),vis) def OnBeforeNavigate2(self,pDisp,url,flags, targetFrameName,postData, headers,cancel): print "At %6.3f OnBeforeNavigate2 on url [%s] on frame [%s]"% \ (time.clock(), url, targetFrameName) def OnCommandStateChange(self, Command, Enable): print 'At %6.3f OnCommandStateChange: %s %s'% \ (time.clock(),Command,Enable) def OnProgressChange(self, nProgress, nProgressMax): msg = 'At %6.3f OnProgressChange progress %d max %d' % ( time.clock(),nProgress, nProgressMax) print msg def OnStatusBar(self, status): msg = 'At %6.3f OnStatusBar %s'%(time.clock(),status) print msg time.clock() # just get clock running print 'At %6.3f win32com.client.DispatchWithEvents'%time.clock() ie = win32com.client.DispatchWithEvents( 'InternetExplorer.Application', events) # NO PUMP MESSAGE print 'At %6.3f set ie.Visible'%time.clock() ie.Visible = 1 print 'At %6.3f set ie.StatusBar false'%time.clock() ie.StatusBar = 0 print 'At %6.3f set ie.StatusBar true'%time.clock() ie.StatusBar = 1 print 'At %6.3f Navigate to http://msdn2.microsoft.com/en-us/library/aa752574.aspx'%time.clock() url = 'http://msdn2.microsoft.com/en-us/library/aa752574.aspx' ie.Navigate(url) print 'At %6.3f back from Navigate'%time.clock() print 'The page should NOT be displayed' print 'Spin for 20 seconds' t0 = time.clock() while time.clock()-t0 < 20: pass print 'At %6.3f pump any trailing messages'%time.clock() print 'The page should NOW display' t0 = time.clock() while time.clock()-t0 < 20: pythoncom.PumpWaitingMessages() # PUMP MESSAGES print '*'*50 print 'At %6.3f Navigate WITH PUMP to http://msdn2.microsoft.com/en-us/library/aa752514.aspx'%time.clock() url = 'http://msdn2.microsoft.com/en-us/library/aa752514.aspx' ie.Navigate(url) print 'At %6.3f back from Navigate and PUMPING'%time.clock() t0 = time.clock() while time.clock()-t0 < 20: pythoncom.PumpWaitingMessages() print 'At %6.3f terminate'%time.clock() --- end code --- --- begin complete test output --- At 0.000 win32com.client.DispatchWithEvents At 1.250 set ie.Visible At 1.299 OnVisible is True At 1.305 set ie.StatusBar false At 1.324 OnStatusBar False At 1.329 set ie.StatusBar true At 1.343 OnCommandStateChange: 2 False At 1.355 OnStatusBar True At 1.356 Navigate to http://msdn2.microsoft.com/en-us/library/aa752574.aspx At 1.358 OnCommandStateChange: 1 False At 1.374 OnBeforeNavigate2 on url [http://msdn2.microsoft.com/en-us/library/aa752574.aspx] on frame [] At 1.407 back from Navigate The page should NOT be displayed Spin for 20 seconds At 21.408 pump any trailing messages The page should NOW display At 21.408 OnCommandStateChange: 2 False At 21.409 OnCommandStateChange: 1 False At 21.444 OnProgressChange progress 0 max 10000 At 21.715 OnCommandStateChange: -1 False At 21.791 OnCommandStateChange: 2 False At 21.798 OnCommandStateChange: 1 False At 21.849 OnCommandStateChange: -1 False At 21.942 OnProgressChange progress 50 max 10000 At 22.441 OnProgressChange progress 100 max 10000 At 22.471 OnProgressChange progress 258300 max 1000000 At 22.472 OnProgressChange progress 272200 max 1000000 At 22.486 OnProgressChange progress 339200 max 1000000 At 22.494 OnProgressChange progress 422900 max 1000000 At 22.557 OnProgressChange progress 1006800 max 1000000 At 27.806 OnProgressChange progress 1000000 max 1000000 At 27.807 OnProgressChange progress -1 max 1000000 At 27.824 OnProgressChange progress 1000000 max 1000000 At 28.115 OnBeforeNavigate2 on url [http://msdn2.microsoft.com/en-us/library/aa752574(d=toc).aspx] on frame [] At 28.138 OnProgressChange progress 1000000 max 10000 At 28.167 OnCommandStateChange: -1 False At 28.306 OnProgressChange progress 0 max 0 At 29.552 OnProgressChange progress 54300 max 1000000 At 29.555 OnProgressChange progress 129300 max 1000000 At 29.557 OnProgressChange progress 214900 max 1000000 At 29.560 OnProgressChange progress 338300 max 1000000 At 29.584 OnProgressChange progress 449600 max 1000000 At 29.587 OnProgressChange progress 476400 max 1000000 At 29.594 OnProgressChange progress 554300 max 1000000 At 29.820 OnCommandStateChange: 2 False At 29.820 OnCommandStateChange: 1 False At 37.530 OnProgressChange progress 1000000 max 1000000 At 37.531 OnProgressChange progress -1 max 1000000 At 37.672 OnCommandStateChange: -1 False At 38.053 OnProgressChange progress 0 max 0 ************************************************** At 41.408 Navigate WITH PUMP to http://msdn2.microsoft.com/en-us/library/aa752514.aspx At 41.414 back from Navigate and PUMPING At 41.430 OnBeforeNavigate2 on url [http://msdn2.microsoft.com/en-us/library/aa752514.aspx] on frame [] At 41.600 OnProgressChange progress 0 max 10000 At 41.607 OnCommandStateChange: -1 False At 42.097 OnProgressChange progress 50 max 10000 At 42.212 OnProgressChange progress 11000 max 1000000 At 42.335 OnCommandStateChange: -1 False At 42.479 OnCommandStateChange: 2 True At 42.480 OnCommandStateChange: 1 False At 42.485 OnCommandStateChange: -1 False At 42.791 OnProgressChange progress 287700 max 1000000 At 42.803 OnProgressChange progress 465400 max 1000000 At 42.806 OnProgressChange progress 995300 max 1000000 At 46.091 OnProgressChange progress 1000000 max 1000000 At 46.092 OnProgressChange progress -1 max 1000000 At 46.102 OnProgressChange progress 1000000 max 1000000 At 46.400 OnBeforeNavigate2 on url [http://msdn2.microsoft.com/en-us/library/aa752514(d=toc).aspx] on frame [] At 46.425 OnProgressChange progress 1000000 max 10000 At 46.431 OnCommandStateChange: -1 False At 46.590 OnProgressChange progress 0 max 0 At 47.680 OnProgressChange progress 96400 max 1000000 At 47.684 OnProgressChange progress 171000 max 1000000 At 47.686 OnProgressChange progress 249300 max 1000000 At 47.700 OnProgressChange progress 424700 max 1000000 At 47.886 OnCommandStateChange: 2 True At 47.887 OnCommandStateChange: 1 False At 54.426 OnProgressChange progress 1000000 max 1000000 At 54.434 OnProgressChange progress -1 max 1000000 At 54.611 OnCommandStateChange: -1 False At 54.955 OnProgressChange progress 0 max 0 At 61.423 terminate --- end complete test output --- From timr at probo.com Thu Jun 7 18:32:29 2007 From: timr at probo.com (Tim Roberts) Date: Thu, 07 Jun 2007 09:32:29 -0700 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <000001c7a919$3b61f320$6701a8c0@rjbmain> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain><09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local><003201c7a832$b24f4880$6701a8c0@rjbmain> <4666E3A3.9080703@probo.com> <000001c7a919$3b61f320$6701a8c0@rjbmain> Message-ID: <4668331D.1020503@probo.com> Richard Bell wrote: > I rewrote the test, see below. When run it behaves as you suggest (see the > test output below). In particular the OnVisible event occurs synchronously > before return from 'ie.Visible = 1' as you suggested. I checked StatusBar > and it appears to be synchronous as well. I assume then that any events > associated with setting IE's properties would also be synchronous, wouldn't > they? > Yes, I would expect that. > But note that when I set StatusBar false the OnStatusBar event occurs. Then > when I set StatusBar true both OnCommandStateChange and OnStatusBar events > occur. I expected the OnStatusBar event but NOT the OnCommandStateChange > event as later in the test (after 21.407) OnCommandStateChange behaves > asynchronously. It's quite possible for a single callback to happen both synchronously and asynchronously, depending on context. In this case, IE probably considers the StatusBar to be one of its "commands", so the OnCommandStateChange makes some sense. > Is there some bit of behavior such that when a synchronous > event occurs other queued events are also processed? About a year ago, Mark > Hammond helped me in this area and memory serves that when any events are > processed they are all processed. Is this true? Is this behavior a > function of COM or of the Python COM interface? > I don't know this, and frankly I'm not sure there are any hard and fast rules to rely on. > More generally, how do I know what COM interactions will generate > synchronous events and which will cause asynchronous events? I'm afraid experience is the only teacher here. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From rbell01824 at earthlink.net Fri Jun 8 01:57:55 2007 From: rbell01824 at earthlink.net (Richard Bell) Date: Thu, 7 Jun 2007 19:57:55 -0400 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <4668331D.1020503@probo.com> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain><09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local><003201c7a832$b24f4880$6701a8c0@rjbmain> <4666E3A3.9080703@probo.com> <000001c7a919$3b61f320$6701a8c0@rjbmain> <4668331D.1020503@probo.com> Message-ID: <000601c7a95f$ab1473a0$6801a8c0@homeoffice.benchmarkinternational.com> Tim Roberts wrote |It's quite possible for a single callback to happen both synchronously |and asynchronously, depending on context. In this case, IE probably |considers the StatusBar to be one of its "commands", so the |OnCommandStateChange makes some sense. Is it then the case that my OnEvent routines should only execute under one of the following conditions? 1 - I interact with the COM target as in ie.Visible = 1 or ie.Navigate2 2 - I execute a pythoncom.PumpWaitingMessages In particular, under no circumstances will my On-event routines execute (apartment-threaded early binding) so that for example: # On-event routines might run across this Ie.Visible = 1 # But once I get here On-event routines will NOT run ... # On-event routines might run across this Ie.Navigate2('www.google.com') # But once I get here On-event routines will NOT run ... tT0 = time.clock() # On-event routines might run across this while time.clock()-t0<10: pythoncom.PumpWaitingMessages # But once I get here On-event routines will NOT run In particular, is it true if I'm automating IE and the user moves or resizes the browser window or some other action that caused events then those events will queue and my OnEvent routines will NOT run until such time as I again interact with COM or pump messages? Thus when I'm not interacting explicitly with COM (apartment-threaded) unanticipated On-event routine execution is NOT possible. One of the reasons I'm focusing on this is that I noticed in the last example that events WERE queued and only became visible when messages were pumped. It seems to me that that in turn means that after my code gets control back and I go off and do whatever then when I once again want to interact with IE and COM I'd best pump messages FIRST to insure that any pending messages are flushed from the queue (at least if my new interactions depend on the future message flow as they do) since some agency outside my program (the user or a bit of script on the page) may have done things that caused events that are NOT associated with my pending interaction. Thanks again for your assistance, it is very valuable and has helped clear up a number of areas I really didn't understand very well. As you might have gathered from the questions, the answers have some fairly consequential design impacts that were certainly not apparent to me based on my initial understanding (or more properly lack of understanding). BTW, my offer of an example still stands and I think I may finally have enough of an understanding to post something if it would be helpful to others. Regards, Richard From timr at probo.com Fri Jun 8 02:47:22 2007 From: timr at probo.com (Tim Roberts) Date: Thu, 07 Jun 2007 17:47:22 -0700 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <000601c7a95f$ab1473a0$6801a8c0@homeoffice.benchmarkinternational.com> References: <000001c7a798$5bcbf7f0$6701a8c0@rjbmain><09af01c7a7c4$8afa3330$1f0a0a0a@enfoldsystems.local><003201c7a832$b24f4880$6701a8c0@rjbmain> <4666E3A3.9080703@probo.com> <000001c7a919$3b61f320$6701a8c0@rjbmain> <4668331D.1020503@probo.com> <000601c7a95f$ab1473a0$6801a8c0@homeoffice.benchmarkinternational.com> Message-ID: <4668A71A.3090406@probo.com> Richard Bell wrote: > Is it then the case that my OnEvent routines should only execute under one > of the following conditions? > > 1 - I interact with the COM target as in ie.Visible = 1 or ie.Navigate2 > 2 - I execute a pythoncom.PumpWaitingMessages > I believe this to be true. You are apartment-threaded, which means you are saying you will only accept events on the thread that created the object. The only ways to accept events on your thread are the two ways you outline above. Now, could a COM object violate that contract and send you events on another thread? Yes, but it would be a COM bug, and Microsoft is pretty careful about having their own objects follow the rules. > In particular, is it true if I'm automating IE and the user moves or resizes > the browser window or some other action that caused events then those events > will queue and my OnEvent routines will NOT run until such time as I again > interact with COM or pump messages? Thus when I'm not interacting > explicitly with COM (apartment-threaded) unanticipated On-event routine > execution is NOT possible. > If you do get them, it is a bug in IE or in COM. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From teekaysoh at gmail.com Fri Jun 8 04:30:44 2007 From: teekaysoh at gmail.com (TK Soh) Date: Thu, 7 Jun 2007 21:30:44 -0500 Subject: [python-win32] path to py2exe-generated package Message-ID: <58b84f8e0706071930i1c19af31pd6525e70e36e0c37@mail.gmail.com> My program uses some custom icons and data that are locate in a subdir within the program root. However, when executing the package created by py2exe, the program was not able to access these icons and data through relative paths. Any advice on how to handle this would be greatly appreciated. Thanks. From mhammond at skippinet.com.au Fri Jun 8 06:46:47 2007 From: mhammond at skippinet.com.au (Mark Hammond) Date: Fri, 8 Jun 2007 14:46:47 +1000 Subject: [python-win32] DispatchWithEvents design question In-Reply-To: <000601c7a95f$ab1473a0$6801a8c0@homeoffice.benchmarkinternational.com> Message-ID: <0bc001c7a988$062e6a20$1f0a0a0a@enfoldsystems.local> > BTW, my offer of an example still stands and I think I may > finally have > enough of an understanding to post something if it would be helpful to > others. That would be most welcome - I'd be happy to include in pywin32 and obviously you could put if anywhere else that takes your fancy... Cheers, Mark From npswarna_13 at yahoo.co.in Fri Jun 8 10:24:45 2007 From: npswarna_13 at yahoo.co.in (swarna np) Date: Fri, 8 Jun 2007 09:24:45 +0100 (BST) Subject: [python-win32] Problem with Raw datatype Message-ID: <500957.86498.qm@web8405.mail.in.yahoo.com> Hi All, I am using Oracle as by DBMS and Python for front end. I am having a problem with 'Raw' data type of Oracle, it is as follows: 1. When I fetch a column whose type is 'Raw' it's being formatted. For ex: The value in the DB is : 'FEEDEE007F91500D9638994600A3C50C' But the python prints it as:''\xfe\xed\xee\x00\x7f\x91P\r\x968\x99F\x00\xa3\xc5\x0c' I want to use the same value in my select statement later. I am not sure how to get back the original raw value from the formatted string by Python. Can you please help me out? Thanks, Swarna --------------------------------- Here?s a new way to find what you're looking for - Yahoo! Answers -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-win32/attachments/20070608/c6a003b1/attachment-0001.html From mbelzile at softimage.com Fri Jun 8 21:26:20 2007 From: mbelzile at softimage.com (=?iso-8859-1?Q?Marc-Andr=E9_Belzile?=) Date: Fri, 8 Jun 2007 15:26:20 -0400 Subject: [python-win32] inspect.getsource fails Message-ID: <0BCB4AE868D8934A8B3DCE3A58126A894EF244@tewk-mbpf3> Hi, I get an IO error when executing some code based on the inspect module: import inspect def FunctionTest(): x = 1 y = 2 return x+1 stringFunction = inspect.getsource(FunctionTest) print stringFunction # ERROR : Traceback (most recent call last): # File "