[python-win32] window events via SetWindowsHookExA

Tim Roberts timr at probo.com
Thu Sep 17 23:03:48 CEST 2009

Antoine Martin wrote:
> I am trying to use SetWindowsHookExA via ctypes to be notified when
> Windows are mapped/unmapped, to get the same functionality as
> SUBSTRUCTURE_MASK events on the root X-window (or is there a better way
> that I have missed?)

WH_CALLWNDPROC is a bit extreme.  The equivalent to mapping and
unmapping in the Windows world is activation, done with the WM_ACTIVATE
and WM_DEACTIVATE messages.  You should be able to monitor those with
WH_CBT, which is a bit lighter weight than the WH_CALLWNDPROC hooks.

There is a problem with your code, however:

> Here is the code:
> WIN_HOOK = CFUNCTYPE(c_long, c_int, c_uint, c_long)
> def register_hook()
>     dll_handle = ctypes.windll.user32._handle
>     self.call_next_hook = ctypes.windll.user32.CallNextHookEx
>     self.hook_handle =
> types.windll.user32.SetWindowsHookExA(WH_CALLWNDPROCRET,
> WIN_HOOK(window_hook), dll_handle, 0)

You are telling it that the function to be called is inside of
user32.dll.  When you install an invasive hook like this, the operating
system actually injects that DLL into every process that owns a window. 
Your hook function is then called in the context of those other
processes.  That's why they tell you that most hook procedures must
reside in a DLL.

In your case, the function address you gave is local to your EXE.  It
won't exist in other processes (or it will point to random memory). 
When the first event occurs, your callback will be called in a thread in
some other process.  That thread gets an exception, because that address
points into random space, and your app is terminated.

There used to be a great project at the University of North Carolina
called pyAA that could do this, but it hasn't been updated past Python
2.4.  At this point, I do not know of a way to implement Windows hooks
in straight Python.

Tim Roberts, timr at probo.com
Providenza & Boekelheide, Inc.

More information about the python-win32 mailing list