Today I would like to talk about how in C# you can hook messages that come to the application. For this we use the SetWindowsHookEx function from user32.dll. The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread. WH_GETMESSAGE installs a hook procedure that monitors messages posted to a message queue.
public static partial class HookManager
{
private const int WH_GETMESSAGE = 3;
private const int WM_KEYDOWN = 0x100;
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, intnCode, IntPtr wParam, ref MSG lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError =true)]
private static extern int SetWindowsHookEx(int idHook, CallbackPtr lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError =true)]
private static extern int UnhookWindowsHookEx(intidHook);
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
public static void Init()
{
if (m_hHook != 0) return;
m_callBack = new CallbackPtr(CallBack);
m_hHook = SetWindowsHookEx(WH_GETMESSAGE, m_callBack,IntPtr.Zero, GetCurrentThreadId());
}
public static void Dispose()
{
if (m_hHook == 0) return;
UnhookWindowsHookEx(m_hHook);
m_hHook = 0;
}
private static int CallBack(int code, IntPtr wParam, refMSG lParam)
{
if (lParam.msg == WM_KEYDOWN && !m_bInHook)
{
m_bInHook = true;
try
{
...
}
catch (Exception ex)
{
m_log.Fatal("UNHANDLED!", ex);
}
finally
{
m_bInHook = false;
}
}
return CallNextHookEx(m_hHook, code, wParam, reflParam);
}
private static CallbackPtr m_callBack;
private delegate int CallbackPtr(int code, IntPtr wp, refMSG lp);
private static int m_hHook;
private static bool m_bInHook = false;
}
* This source code was highlighted with Source Code Highlighter.