<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 11 (filtered medium)">
<style>
<!--
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";}
a:link, span.MsoHyperlink
        {color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:Arial;
        color:windowtext;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
        {page:Section1;}
-->
</style>
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I’m not sure if this is the right place to ask, but
here goes. I would like to monitor system wide window messages to see when
windows are created/destroyed. The reason being I am writing a small app that
will reposition windows automatically. I thought of a couple of different
approaches.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>First:<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>In a loop: use win32gui.EnumWindows() to see what windows
are currently displayed and in the next iteration of the loop, see what windows
have changed since the last run. This somewhat worked, but doesn’t catch
only new windows. For example, some programs may change their title bar text
while they are displaying, causing some problems.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Second:<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Also in a loop enumerate running processes. If I see a new
process that I want to find windows for, act accordingly. However, this ate up
bunches of CPU enumerating processes over and over. The following code demonstrates
that:<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>import win32com.client<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>wmi = win32com.client.GetObject('winmgmts:')<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>while self.keep_looking:<o:p></o:p></span></font></p>
<p class=MsoNormal style='text-indent:.5in'><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial'>time.sleep(0.1)<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'> if
self.processes == []:<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'> for
p in wmi.InstancesOf('win32_process'):<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'> process_name
= str(p.Properties_('Name'))<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'> process_id
= int(p.Properties_('ProcessId'))<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'> print
process_name, process_id<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>So then I thought there must be a way to receive a message
when a new window is created so I can act accordingly. After some research it
appears that SetWindowsHookEx is what I’m after, however it is not
wrapped by python-win32. However ctypes will let me call those functions, but I’m
not quite sure how to proceed. I found a page explaining how to do it in VB,
and I’ve created my code based on it. The site is down, but can be viewed
with google cache.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>http://209.85.165.104/search?q=cache:orLCeZV4kjoJ:04.code-hosting.com/Visual_Basic/1353728-Notification-of-program-launch-and-termination+python+SetWindowsHookExA&hl=en&ct=clnk&cd=6&gl=us<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I’m not sure where to go from here though. The
following runs without error, but doesn’t show any messages. I know I
need to setup a loop, but how do I get the messages? Do I need to create a
window with the win32gui functions and read it’s messages? Any help would
be greatly appreciated.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>import win32con, win32gui, ctypes<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>hwnd = win32gui.GetActiveWindow()<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>msgShellHook =
ctypes.windll.user32.RegisterWindowMessageA("SHELLHOOK")<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>hShellLib =
ctypes.windll.kernel32.LoadLibraryA("shell32") #GetModuleHandleA also
return the same value<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>lpfnHookProc = ctypes.windll.kernel32.GetProcAddress(hShellLib,
"ShellHookProc")<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>ctypes.windll.user32.RegisterShellHookWindow(hwnd)<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>hHook =
ctypes.windll.user32.SetWindowsHookExA(win32con.WH_SHELL, lpfnHookProc,
hShellLib, 0)<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Also, some useful links:<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>SetWindowsHookEx <a
href="http://msdn2.microsoft.com/en-us/library/ms644990.aspx">http://msdn2.microsoft.com/en-us/library/ms644990.aspx</a><o:p></o:p></span></font></p>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>GetProcAddress <a
href="http://msdn2.microsoft.com/en-us/library/ms683212.aspx">http://msdn2.microsoft.com/en-us/library/ms683212.aspx</a><o:p></o:p></span></font></p>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>RegisterWindowMessage <a
href="http://msdn2.microsoft.com/en-us/library/ms644947(VS.85).aspx">http://msdn2.microsoft.com/en-us/library/ms644947(VS.85).aspx</a><o:p></o:p></span></font></p>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>LoadLibrary </span></font><a
href="http://msdn2.microsoft.com/en-us/library/ms684175(VS.85).aspx">http://msdn2.microsoft.com/en-us/library/ms684175(VS.85).aspx</a><o:p></o:p></p>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>-Kyle Rickey</span></font><o:p></o:p></p>
</div>
</body>
</html>