Re: How to correctly handle events using win32com ?
David Sansom <[email protected]> Sat, 30 Nov 2024 19:56:02 +0000
| Newsgroups | gmane.comp.python.windows |
|---|---|
| Message-ID | <[email protected]> |
--===============9109090394550386517== Content-Type: multipart/alternative; boundary=Apple-Mail-7A34B03B-14C8-42EA-B37F-B36D12C3E156 Content-Transfer-Encoding: 7bit --Apple-Mail-7A34B03B-14C8-42EA-B37F-B36D12C3E156 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable <html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=3D= utf-8"></head><body dir=3D"auto">Glad it=E2=80=99s working!<div><br></div><d= iv>Your Python code and the Excel application are running in separate proces= ses that (usually) only communicate via COM, not the windows messaging syste= m.</div><div><br></div><div>When Excel wants to quit it posts a WM_QUIT mess= age to its OWN message queue which, once processed, will terminate the main E= xcel application thread=E2=80=99s message loop. The Excel process will then t= erminate (usually).<br><div><br></div><div>Your Python code may or may not h= ave a message loop. Calling PumpMessages() creates a message loop in your Py= thon application=E2=80=99s main thread. It is there simply to stop your code= running through to completion and exiting. It also allows execution of othe= r routines in your code. You have to send a quit message to this loop yourse= lf when you know you are done with it and you want your application to termi= nate.</div><div><br></div><div>Excel doesn=E2=80=99t know much about your Py= thon calling code (and certainly not whether your code has a message loop) e= xcept that your code has notified Excel (using the WithEvents() call) that i= t wants Excel to fire the supplied callback whenever an event occurs. Your P= ython code then decides if it cares about the Event, otherwise ignoring it. T= hat is why you have to write a specific handler for OnBeforeClose and also d= ecide what to do when the event is fired. Excel can=E2=80=99t decide that fo= r you.</div><div><br></div><div>Best</div><div><br></div><div>DS</div><div><= div><div><br id=3D"lineBreakAtBeginningOfSignature"><div dir=3D"ltr">Sent fr= om my iPhone</div><div dir=3D"ltr"><br><blockquote type=3D"cite">On 30 Nov 2= 024, at 17:28, Gauthier ABRIAL <[email protected]> wrote:<br><br></= blockquote></div><blockquote type=3D"cite"><div dir=3D"ltr">=EF=BB=BF <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8"> <div class=3D"elementToProof" style=3D"font-family: Calibri, Helvetica, sans= -serif; font-size: 12pt; color: rgb(0, 0, 0);"> <a href=3D"mailto:[email protected]" id=3D"OWAAM831856" class=3D"tWKOu me= ntion ms-bgc-nlr ms-fcl-b">@David Sansom</a>: amazing that's exactly what I w= as looking for ! That works now, PumpMessages() is correctly returning when I= call PostQuitMessage().</div> <div class=3D"elementToProof" style=3D"font-family: Calibri, Helvetica, sans= -serif; font-size: 12pt; color: rgb(0, 0, 0);"> 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 work= able solution and I know that the way I use win32com seems to make sense (no= body gave me any pushback here on the way I use it).</div> <div class=3D"elementToProof" style=3D"font-family: Calibri, Helvetica, sans= -serif; font-size: 12pt; color: rgb(0, 0, 0);"> Thanks a lot everybody.</div> <div class=3D"elementToProof" style=3D"font-family: Calibri, Helvetica, sans= -serif; font-size: 12pt; color: rgb(0, 0, 0);"> G.</div> <div id=3D"appendonsend"></div> <hr style=3D"display:inline-block;width:98%" tabindex=3D"-1"> <div id=3D"divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, sans-serif" sty= le=3D"font-size:11pt" color=3D"#000000"><b>De :</b> David Sansom <david@e= lkpoint.co.uk><br> <b>Envoy=C3=A9 :</b> 30 novembre 2024 05:04<br> <b>=C3=80 :</b> Gauthier ABRIAL <[email protected]><br> <b>Cc :</b> [email protected] <[email protected]><br>= <b>Objet :</b> Re: [python-win32] How to correctly handle events using win32= com ?</font> <div> </div> </div> <div dir=3D"auto">Hi, <div><br> </div> <div> <blockquote type=3D"cite"> <div dir=3D"ltr"> <ul data-editing-info=3D"{"applyListStyleFromLevel":false,"un= orderedStyleType":2}"> <li style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; list-= style-type:"- ""> <div class=3D"x_elementToProof"> I guess I should send a WM_QUIT messag= e but I don't know how.</div> </li></ul> </div> </blockquote> <div><br> </div> <div>Have you tried win32api.PostQuitMessage() in the event handler for Code= 1?</div> <div><br> </div> <div>DS</div> <div><br id=3D"x_lineBreakAtBeginningOfSignature"> <div dir=3D"ltr">Sent from my iPhone</div> <div dir=3D"ltr"><br> <blockquote type=3D"cite">On 29 Nov 2024, at 18:00, Gauthier ABRIAL <g_ab= [email protected]> wrote:<br> <br> </blockquote> </div> <blockquote type=3D"cite"> <div dir=3D"ltr">=EF=BB=BF <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> Hello,</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> 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 thin= gs.</div> <ul data-editing-info=3D"{"applyListStyleFromLevel":false,"un= orderedStyleType":2}"> <li style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color= :rgb(0,0,0); list-style-type:"- ""> <div class=3D"x_elementToProof">Code1 below use pythoncom.PumpMessages() but= I don't know how to stop it when the Excel is closing. I guess I should sen= d a WM_QUIT message but I don't know how.</div> </li><li style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; c= olor:rgb(0,0,0); list-style-type:"- ""> <div class=3D"x_elementToProof" style=3D"margin:0px">Code2 below use a while= loop on pythoncom.PumpWaitingMessages() but once I stop the loop the COM se= rver freeze as it is waiting for the messages it sends to be processed befor= e closing. I guess I should pump all the remaining messages but I don't know how.</div> </li></ul> <div class=3D"x_elementToProof" style=3D"margin:0px; font-family:Calibri,Hel= vetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> Maybe I should use a totally different approach.</div> <div class=3D"x_elementToProof" style=3D"margin:0px; font-family:Calibri,Hel= vetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> Thanks a lot for your help.</div> <div class=3D"x_elementToProof" style=3D"margin:0px; font-family:Calibri,Hel= vetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> <br> </div> <div class=3D"x_elementToProof" style=3D"margin:0px; font-family:Calibri,Hel= vetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> G.</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> <br> </div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> -------------------- Code1 Starts -----------------------</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> import win32com.client as win32</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> import pythoncom</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> <br> </div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> #The event handlers</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> class wbEvents:</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> def OnBeforeClose(self, Cancel):</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> print('Closing Workbook')</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> # Send WM_QUIT here ?</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> <br> </div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlApp =3D win32.Dispatch("Excel.Application") #Open Excel</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlApp.Visible=3DTrue #Make Excel Visible</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlwb =3D xlApp.Workbooks.Add() #Create a workbook</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> ws=3Dxlwb.Sheets("Sheet1") #Get the first worksheet</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xl_events=3Dwin32.WithEvents(xlwb,wbEvents) #Add and Event handler</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> pythoncom.PumpMessages()</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> -------------------- Code1 Ends -----------------------</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> <br> </div> <div class=3D"x_elementToProof" style=3D"text-align:left; text-indent:0px; m= argin:0px; font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:r= gb(0,0,0)"> -------------------- Code2 Starts -----------------------</div> <div style=3D"text-align:left; text-indent:0px; margin:0px; font-family:Cali= bri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> import win32com.client as win32</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> import pythoncom</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> import time</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> <br> </div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> #The event handlers</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> class wbEvents:</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> def OnBeforeClose(self, Cancel):</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> print('Closing Workbook')</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> global keepOpen</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> keepOpen =3D False</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> <br> </div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlApp =3D win32.Dispatch("Excel.Application") #Open Excel</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlApp.Visible=3DTrue #Make Excel Visible</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xlwb =3D xlApp.Workbooks.Add() #Create a workbook</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> ws=3Dxlwb.Sheets("Sheet1") #Get the first worksheet</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> xl_events=3Dwin32.WithEvents(xlwb,wbEvents) #Add and Event handler</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> # define initalizer</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> keepOpen =3D True</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> while keepOpen:</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> time.sleep(0.1)</div> <div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo= r:rgb(0,0,0)"> pythoncom.PumpWaitingMessages()</div> <div class=3D"x_elementToProof" style=3D"text-align:left; text-indent:0px; m= argin:0px; font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:r= gb(0,0,0)"> -------------------- Code2 Ends -----------------------</div> <div class=3D"x_elementToProof" style=3D"font-family:Calibri,Helvetica,sans-= serif; font-size:12pt; color:rgb(0,0,0)"> <br> </div> <span>_______________________________________________</span><br> <span>python-win32 mailing list</span><br> <span>[email protected]</span><br> <span>https://mail.python.org/mailman/listinfo/python-win32</span><br> </div> </blockquote> </div> </div> </div> </div></blockquote></div></div></div></div></body></html>= --Apple-Mail-7A34B03B-14C8-42EA-B37F-B36D12C3E156-- --===============9109090394550386517== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ python-win32 mailing list [email protected] https://mail.python.org/mailman/listinfo/python-win32 --===============9109090394550386517==--