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 &lt;[email protected]&gt; 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 &lt;david@e=
lkpoint.co.uk&gt;<br>
<b>Envoy=C3=A9 :</b> 30 novembre 2024 05:04<br>
<b>=C3=80 :</b> Gauthier ABRIAL &lt;[email protected]&gt;<br>
<b>Cc&nbsp;:</b> [email protected] &lt;[email protected]&gt;<br>=

<b>Objet :</b> Re: [python-win32] How to correctly handle events using win32=
com ?</font>
<div>&nbsp;</div>
</div>
<div dir=3D"auto">Hi,
<div><br>
</div>
<div>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<ul data-editing-info=3D"{&quot;applyListStyleFromLevel&quot;:false,&quot;un=
orderedStyleType&quot;:2}">
<li style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; list-=
style-type:&quot;- &quot;">
<div class=3D"x_elementToProof">&nbsp;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 &lt;g_ab=
[email protected]&gt; 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"{&quot;applyListStyleFromLevel&quot;:false,&quot;un=
orderedStyleType&quot;:2}">
<li style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color=
:rgb(0,0,0); list-style-type:&quot;- &quot;">
<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:&quot;- &quot;">
<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)">
&nbsp; &nbsp; def OnBeforeClose(self, Cancel):</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; &nbsp; &nbsp; print('Closing Workbook')</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; &nbsp; &nbsp; # 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)">
&nbsp; &nbsp; def OnBeforeClose(self, Cancel):</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; &nbsp; &nbsp; print('Closing Workbook')</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; &nbsp; &nbsp; global keepOpen</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; &nbsp; &nbsp; 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)">
&nbsp; &nbsp; time.sleep(0.1)</div>
<div style=3D"font-family:Calibri,Helvetica,sans-serif; font-size:12pt; colo=
r:rgb(0,0,0)">
&nbsp; &nbsp; 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==--