Hook WH_CALLWNDPROC and capture all WM_ACTIVATEAPP

5 posts in this topic

alexanderdillard 0

Warning: The code I have posted is relatively low-level system code. As such, please do not attempt to run it unless you are sure you know what you are doing. Furthermore, don't attempt to run it until after reading my entire post.

Simple version of my question: Can AutoIt be used to install system hooks of the WH_CALLWNDPROC type?

Preliminary (presently very unsure) answer: perhaps not...

Slightly more detail: I have been attempting to create a WH_CALLWNDPROC type hook procedure using _WinAPI_SetWindowsHookEx() but so far my efforts have failed. If you know how to do this properly (or are certain AutoIt can't do it...) please advise.

A lot more detail: What I originally set out to do was create a script that always knows the handle of the window which was active prior to the script becoming active. My initial solution was to use GUIRegisterMsg($WM_NCLBUTTONDOWN, 'titleBarClick') and then in my 'titleBarClick' function do the following:

So, based on the idea in the above Stack Overflow link I decided attempt a more generalized solution to getting the handle of the prior active window by hooking WH_CALLWNDPROC and keeping track of all WM_ACTIVATEAPP messages. My starting point was the _WinAPI_SetWindowsHookEx() example code found at http://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_SetWindowsHookEx.htm After going through the example code I removed all the 'fluff' and reduced it down to a prototype of sorts:

In the above prototype code the hook procedure type is set to WH_KEYBOARD_LL, which seems to work fine. However, after testing the above with all 15 of the hook procedure types / idHook values I have found it works for only 12 of the 15. The following three procedure types give problems: WH_CALLWNDPROC, WH_CALLWNDPROCRET and WH_DEBUG. Note that 'problems' is probably an understatement, on my system (XP SP3) swapping any of the three 'problematic' hook procedure types in to the above code totally crashes the OS (killing AutoIt with the Task Manager doesn't help -- a reboot is required). In fact, the crash is about the most violent I have seen in XP ever (it even triggers Data Execution Prevention / DEP). I'm not sure what would happen in Windows 7. If you experiment with the above code please be extremely careful.

Link to post

Share on other sites

alexanderdillard 0

I tried your code, which works fine on my system but as far as I can only registers events associated with itself. What I'm really looking for is a way to detect every single WM_ACTIVATEAPP event no matter which running program it is associated with. I'm guessing your code is limitied to monitoring itself because you set $dwThreadId to the return value of _WinAPI_GetCurrentThreadId(). I tried changing $dwThreadId to 0, since the AutoIt and MSDN documentation seem to indicate that would lead to all threads being monitored. However, after making that change it appears the hook procedure _MyProc() is never called. So I remain confused. Also, why set $hmod to 0 rather than the return value of _WinAPI_GetModuleHandle(0)?

Share this post

Link to post

Share on other sites

LarsJ 497

This is just a simple example that shows how to use a $WH_CALLWNDPROC hook.

The main issue for catching global events is that the callback procedure must be implemented in a DLL. This is very clearly described in the MSDN documentation. And then you use $hMod as a handle for the DLL.