From g_abrial at hotmail.com Fri Nov 29 12:17:12 2024 From: g_abrial at hotmail.com (Gauthier ABRIAL) Date: Fri, 29 Nov 2024 17:17:12 +0000 Subject: [python-win32] How to correctly handle events using win32com ? Message-ID: Hello, I'm looking for some advice on how to correctly handle events using win32com. If I take the example of a very simple Excel automation, I tested two things. * Code1 below use pythoncom.PumpMessages() but I don't know how to stop it when the Excel is closing. I guess I should send a WM_QUIT message but I don't know how. * Code2 below use a while loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM server freeze as it is waiting for the messages it sends to be processed before closing. I guess I should pump all the remaining messages but I don't know how. Maybe I should use a totally different approach. Thanks a lot for your help. G. -------------------- Code1 Starts ----------------------- import win32com.client as win32 import pythoncom #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') # Send WM_QUIT here ? xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler pythoncom.PumpMessages() -------------------- Code1 Ends ----------------------- -------------------- Code2 Starts ----------------------- import win32com.client as win32 import pythoncom import time #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') global keepOpen keepOpen = False xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler # define initalizer keepOpen = True while keepOpen: time.sleep(0.1) pythoncom.PumpWaitingMessages() -------------------- Code2 Ends ----------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: From mhammond at skippinet.com.au Fri Nov 29 14:10:42 2024 From: mhammond at skippinet.com.au (Mark Hammond) Date: Fri, 29 Nov 2024 14:10:42 -0500 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: References: Message-ID: <2abd8ab9-f2f0-4aff-9161-333c723df89a@skippinet.com.au> It's been a while since I've done any of this, but I think there's an "xlApp.Quit()" method you can use? If so, then you might be able to break out of the look when "PumpWaitingMessages()" returns 1 - that will mean the message queue has received a WM_QUIT. On 2024-11-29 12:17 p.m., Gauthier ABRIAL wrote: > Hello, > I'm looking for some advice on how to correctly handle events using > win32com. If I take the example of a very simple Excel automation, I > tested two things. > > * > Code1 below use pythoncom.PumpMessages() but I don't know how to > stop it when the Excel is closing. I guess I should send a WM_QUIT > message but I don't know how. > * > Code2 below use a while loop on pythoncom.PumpWaitingMessages() > but once I stop the loop the COM server freeze as it is waiting > for the messages it sends to be processed before closing. I guess > I should pump all the remaining messages but I don't know how. > > Maybe I should use a totally different approach. > Thanks a lot for your help. > > G. > > -------------------- Code1 Starts ----------------------- > import win32com.client as win32 > import pythoncom > > #The event handlers > class wbEvents: > ? ? def OnBeforeClose(self, Cancel): > ? ? ? ? print('Closing Workbook') > ? ? ? ? # Send WM_QUIT here ? > > xlApp = win32.Dispatch("Excel.Application") #Open Excel > xlApp.Visible=True #Make Excel Visible > xlwb = xlApp.Workbooks.Add() #Create a workbook > ws=xlwb.Sheets("Sheet1") #Get the first worksheet > xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler > pythoncom.PumpMessages() > -------------------- Code1 Ends ----------------------- > > -------------------- Code2 Starts ----------------------- > import win32com.client as win32 > import pythoncom > import time > > #The event handlers > class wbEvents: > ? ? def OnBeforeClose(self, Cancel): > ? ? ? ? print('Closing Workbook') > ? ? ? ? global keepOpen > ? ? ? ? keepOpen = False > > xlApp = win32.Dispatch("Excel.Application") #Open Excel > xlApp.Visible=True #Make Excel Visible > xlwb = xlApp.Workbooks.Add() #Create a workbook > ws=xlwb.Sheets("Sheet1") #Get the first worksheet > xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler > # define initalizer > keepOpen = True > while keepOpen: > ? ? time.sleep(0.1) > ? ? pythoncom.PumpWaitingMessages() > -------------------- Code2 Ends ----------------------- > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dornech at gmx.de Fri Nov 29 14:48:35 2024 From: dornech at gmx.de (dornech) Date: Fri, 29 Nov 2024 20:48:35 +0100 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: <2abd8ab9-f2f0-4aff-9161-333c723df89a@skippinet.com.au> References: <2abd8ab9-f2f0-4aff-9161-333c723df89a@skippinet.com.au> Message-ID: <2ce264b9-9c5f-4844-9752-5460a577e27e@gmx.de> Hi there, exactly, Mark is right on this. You can use very COM object method as you use out of VBA for example. I am working on a wrapper for a more "pythonized" access to the EXCEL API, you may have alokk on it as soon as it is published. BG Chris Am 29.11.2024 um 20:10 schrieb Mark Hammond: > > It's been a while since I've done any of this, but I think there's an > "xlApp.Quit()" method you can use? If so, then you might be able to > break out of the look when "PumpWaitingMessages()" returns 1 - that > will mean the message queue has received a WM_QUIT. > > > On 2024-11-29 12:17 p.m., Gauthier ABRIAL wrote: >> Hello, >> I'm looking for some advice on how to correctly handle events using >> win32com. If I take the example of a very simple Excel automation, I >> tested two things. >> >> * >> Code1 below use pythoncom.PumpMessages() but I don't know how to >> stop it when the Excel is closing. I guess I should send a >> WM_QUIT message but I don't know how. >> * >> Code2 below use a while loop on pythoncom.PumpWaitingMessages() >> but once I stop the loop the COM server freeze as it is waiting >> for the messages it sends to be processed before closing. I guess >> I should pump all the remaining messages but I don't know how. >> >> Maybe I should use a totally different approach. >> Thanks a lot for your help. >> >> G. >> >> -------------------- Code1 Starts ----------------------- >> import win32com.client as win32 >> import pythoncom >> >> #The event handlers >> class wbEvents: >> ? ? def OnBeforeClose(self, Cancel): >> ? ? ? ? print('Closing Workbook') >> ? ? ? ? # Send WM_QUIT here ? >> >> xlApp = win32.Dispatch("Excel.Application") #Open Excel >> xlApp.Visible=True #Make Excel Visible >> xlwb = xlApp.Workbooks.Add() #Create a workbook >> ws=xlwb.Sheets("Sheet1") #Get the first worksheet >> xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler >> pythoncom.PumpMessages() >> -------------------- Code1 Ends ----------------------- >> >> -------------------- Code2 Starts ----------------------- >> import win32com.client as win32 >> import pythoncom >> import time >> >> #The event handlers >> class wbEvents: >> ? ? def OnBeforeClose(self, Cancel): >> ? ? ? ? print('Closing Workbook') >> ? ? ? ? global keepOpen >> ? ? ? ? keepOpen = False >> >> xlApp = win32.Dispatch("Excel.Application") #Open Excel >> xlApp.Visible=True #Make Excel Visible >> xlwb = xlApp.Workbooks.Add() #Create a workbook >> ws=xlwb.Sheets("Sheet1") #Get the first worksheet >> xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler >> # define initalizer >> keepOpen = True >> while keepOpen: >> ? ? time.sleep(0.1) >> ? ? pythoncom.PumpWaitingMessages() >> -------------------- Code2 Ends ----------------------- >> >> >> _______________________________________________ >> python-win32 mailing list >> python-win32 at python.org >> https://mail.python.org/mailman/listinfo/python-win32 > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From g_abrial at hotmail.com Fri Nov 29 15:01:39 2024 From: g_abrial at hotmail.com (Gauthier ABRIAL) Date: Fri, 29 Nov 2024 20:01:39 +0000 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: <2abd8ab9-f2f0-4aff-9161-333c723df89a@skippinet.com.au> References: <2abd8ab9-f2f0-4aff-9161-333c723df89a@skippinet.com.au> Message-ID: For some reasons the PumpWaitingMessages() is never returning 1, even if it seems that Excel has been properly closed and the process ended. My problem is that once I have called "WithEvents", if I stop calling PumpWaitingMessages() Excel is freezing because it's waiting for the events to be processed. Is there any way to "undo" what "WithEvents" is doing so that the server (Excel) is not waiting for the message to be pumped (and do not freeze if I stop calling PumpWaitingMessages()) ? Thanks a lot for your help, G. ________________________________ De : Mark Hammond Envoy? : 29 novembre 2024 14:10 ? : Gauthier ABRIAL ; python-win32 at python.org Objet : Re: [python-win32] How to correctly handle events using win32com ? It's been a while since I've done any of this, but I think there's an "xlApp.Quit()" method you can use? If so, then you might be able to break out of the look when "PumpWaitingMessages()" returns 1 - that will mean the message queue has received a WM_QUIT. On 2024-11-29 12:17 p.m., Gauthier ABRIAL wrote: Hello, I'm looking for some advice on how to correctly handle events using win32com. If I take the example of a very simple Excel automation, I tested two things. * Code1 below use pythoncom.PumpMessages() but I don't know how to stop it when the Excel is closing. I guess I should send a WM_QUIT message but I don't know how. * Code2 below use a while loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM server freeze as it is waiting for the messages it sends to be processed before closing. I guess I should pump all the remaining messages but I don't know how. Maybe I should use a totally different approach. Thanks a lot for your help. G. -------------------- Code1 Starts ----------------------- import win32com.client as win32 import pythoncom #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') # Send WM_QUIT here ? xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler pythoncom.PumpMessages() -------------------- Code1 Ends ----------------------- -------------------- Code2 Starts ----------------------- import win32com.client as win32 import pythoncom import time #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') global keepOpen keepOpen = False xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler # define initalizer keepOpen = True while keepOpen: time.sleep(0.1) pythoncom.PumpWaitingMessages() -------------------- Code2 Ends ----------------------- _______________________________________________ python-win32 mailing list python-win32 at python.org https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From david at elkpoint.co.uk Sat Nov 30 05:04:52 2024 From: david at elkpoint.co.uk (David Sansom) Date: Sat, 30 Nov 2024 10:04:52 +0000 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: References: Message-ID: <3512265B-4945-4F3B-A0DE-A4DAA9544102@elkpoint.co.uk> Hi, > I guess I should send a WM_QUIT message but I don't know how. Have you tried win32api.PostQuitMessage() in the event handler for Code 1? DS Sent from my iPhone > On 29 Nov 2024, at 18:00, Gauthier ABRIAL wrote: > > ? > Hello, > I'm looking for some advice on how to correctly handle events using win32com. If I take the example of a very simple Excel automation, I tested two things. > Code1 below use pythoncom.PumpMessages() but I don't know how to stop it when the Excel is closing. I guess I should send a WM_QUIT message but I don't know how. > Code2 below use a while loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM server freeze as it is waiting for the messages it sends to be processed before closing. I guess I should pump all the remaining messages but I don't know how. > Maybe I should use a totally different approach. > Thanks a lot for your help. > > G. > > -------------------- Code1 Starts ----------------------- > import win32com.client as win32 > import pythoncom > > #The event handlers > class wbEvents: > def OnBeforeClose(self, Cancel): > print('Closing Workbook') > # Send WM_QUIT here ? > > xlApp = win32.Dispatch("Excel.Application") #Open Excel > xlApp.Visible=True #Make Excel Visible > xlwb = xlApp.Workbooks.Add() #Create a workbook > ws=xlwb.Sheets("Sheet1") #Get the first worksheet > xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler > pythoncom.PumpMessages() > -------------------- Code1 Ends ----------------------- > > -------------------- Code2 Starts ----------------------- > import win32com.client as win32 > import pythoncom > import time > > #The event handlers > class wbEvents: > def OnBeforeClose(self, Cancel): > print('Closing Workbook') > global keepOpen > keepOpen = False > > xlApp = win32.Dispatch("Excel.Application") #Open Excel > xlApp.Visible=True #Make Excel Visible > xlwb = xlApp.Workbooks.Add() #Create a workbook > ws=xlwb.Sheets("Sheet1") #Get the first worksheet > xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler > # define initalizer > keepOpen = True > while keepOpen: > time.sleep(0.1) > pythoncom.PumpWaitingMessages() > -------------------- Code2 Ends ----------------------- > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From g_abrial at hotmail.com Sat Nov 30 12:30:05 2024 From: g_abrial at hotmail.com (Gauthier ABRIAL) Date: Sat, 30 Nov 2024 17:30:05 +0000 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: <3512265B-4945-4F3B-A0DE-A4DAA9544102@elkpoint.co.uk> References: <3512265B-4945-4F3B-A0DE-A4DAA9544102@elkpoint.co.uk> Message-ID: @David Sansom: amazing that's exactly what I was looking for ! That works now, PumpMessages() is correctly returning when I call PostQuitMessage(). So the reason why Excel is not sending the WM_QUIT message by itself (or why PumpMessage() is not receiving it) is still unclear to me but I have a workable solution and I know that the way I use win32com seems to make sense (nobody gave me any pushback here on the way I use it). Thanks a lot everybody. G. ________________________________ De : David Sansom Envoy? : 30 novembre 2024 05:04 ? : Gauthier ABRIAL Cc : python-win32 at python.org Objet : Re: [python-win32] How to correctly handle events using win32com ? Hi, * I guess I should send a WM_QUIT message but I don't know how. Have you tried win32api.PostQuitMessage() in the event handler for Code 1? DS Sent from my iPhone On 29 Nov 2024, at 18:00, Gauthier ABRIAL wrote: ? Hello, I'm looking for some advice on how to correctly handle events using win32com. If I take the example of a very simple Excel automation, I tested two things. * Code1 below use pythoncom.PumpMessages() but I don't know how to stop it when the Excel is closing. I guess I should send a WM_QUIT message but I don't know how. * Code2 below use a while loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM server freeze as it is waiting for the messages it sends to be processed before closing. I guess I should pump all the remaining messages but I don't know how. Maybe I should use a totally different approach. Thanks a lot for your help. G. -------------------- Code1 Starts ----------------------- import win32com.client as win32 import pythoncom #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') # Send WM_QUIT here ? xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler pythoncom.PumpMessages() -------------------- Code1 Ends ----------------------- -------------------- Code2 Starts ----------------------- import win32com.client as win32 import pythoncom import time #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') global keepOpen keepOpen = False xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler # define initalizer keepOpen = True while keepOpen: time.sleep(0.1) pythoncom.PumpWaitingMessages() -------------------- Code2 Ends ----------------------- _______________________________________________ python-win32 mailing list python-win32 at python.org https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From david at elkpoint.co.uk Sat Nov 30 14:56:02 2024 From: david at elkpoint.co.uk (David Sansom) Date: Sat, 30 Nov 2024 19:56:02 +0000 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: References: Message-ID: <1E2C9753-B172-42A6-B1EF-0FAA20D52B1E@elkpoint.co.uk> An HTML attachment was scrubbed... URL: From g_abrial at hotmail.com Sat Nov 30 22:07:05 2024 From: g_abrial at hotmail.com (Gauthier ABRIAL) Date: Sun, 1 Dec 2024 03:07:05 +0000 Subject: [python-win32] How to correctly handle events using win32com ? In-Reply-To: <1E2C9753-B172-42A6-B1EF-0FAA20D52B1E@elkpoint.co.uk> References: <1E2C9753-B172-42A6-B1EF-0FAA20D52B1E@elkpoint.co.uk> Message-ID: Thanks a lot, that explanation is very useful ! Regards, G. T?l?chargez Outlook pour iOS ________________________________ De : David Sansom Envoy? : Saturday, November 30, 2024 2:56:02 PM ? : Gauthier ABRIAL Cc : python-win32 at python.org Objet : Re: [python-win32] How to correctly handle events using win32com ? Glad it?s working! Your Python code and the Excel application are running in separate processes that (usually) only communicate via COM, not the windows messaging system. When Excel wants to quit it posts a WM_QUIT message to its OWN message queue which, once processed, will terminate the main Excel application thread?s message loop. The Excel process will then terminate (usually). Your Python code may or may not have a message loop. Calling PumpMessages() creates a message loop in your Python application?s main thread. It is there simply to stop your code running through to completion and exiting. It also allows execution of other routines in your code. You have to send a quit message to this loop yourself when you know you are done with it and you want your application to terminate. Excel doesn?t know much about your Python calling code (and certainly not whether your code has a message loop) except that your code has notified Excel (using the WithEvents() call) that it wants Excel to fire the supplied callback whenever an event occurs. Your Python code then decides if it cares about the Event, otherwise ignoring it. That is why you have to write a specific handler for OnBeforeClose and also decide what to do when the event is fired. Excel can?t decide that for you. Best DS Sent from my iPhone On 30 Nov 2024, at 17:28, Gauthier ABRIAL wrote: ? @David Sansom: amazing that's exactly what I was looking for ! That works now, PumpMessages() is correctly returning when I call PostQuitMessage(). So the reason why Excel is not sending the WM_QUIT message by itself (or why PumpMessage() is not receiving it) is still unclear to me but I have a workable solution and I know that the way I use win32com seems to make sense (nobody gave me any pushback here on the way I use it). Thanks a lot everybody. G. ________________________________ De : David Sansom Envoy? : 30 novembre 2024 05:04 ? : Gauthier ABRIAL Cc : python-win32 at python.org Objet : Re: [python-win32] How to correctly handle events using win32com ? Hi, * I guess I should send a WM_QUIT message but I don't know how. Have you tried win32api.PostQuitMessage() in the event handler for Code 1? DS Sent from my iPhone On 29 Nov 2024, at 18:00, Gauthier ABRIAL wrote: ? Hello, I'm looking for some advice on how to correctly handle events using win32com. If I take the example of a very simple Excel automation, I tested two things. * Code1 below use pythoncom.PumpMessages() but I don't know how to stop it when the Excel is closing. I guess I should send a WM_QUIT message but I don't know how. * Code2 below use a while loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM server freeze as it is waiting for the messages it sends to be processed before closing. I guess I should pump all the remaining messages but I don't know how. Maybe I should use a totally different approach. Thanks a lot for your help. G. -------------------- Code1 Starts ----------------------- import win32com.client as win32 import pythoncom #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') # Send WM_QUIT here ? xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler pythoncom.PumpMessages() -------------------- Code1 Ends ----------------------- -------------------- Code2 Starts ----------------------- import win32com.client as win32 import pythoncom import time #The event handlers class wbEvents: def OnBeforeClose(self, Cancel): print('Closing Workbook') global keepOpen keepOpen = False xlApp = win32.Dispatch("Excel.Application") #Open Excel xlApp.Visible=True #Make Excel Visible xlwb = xlApp.Workbooks.Add() #Create a workbook ws=xlwb.Sheets("Sheet1") #Get the first worksheet xl_events=win32.WithEvents(xlwb,wbEvents) #Add and Event handler # define initalizer keepOpen = True while keepOpen: time.sleep(0.1) pythoncom.PumpWaitingMessages() -------------------- Code2 Ends ----------------------- _______________________________________________ python-win32 mailing list python-win32 at python.org https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: