using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace GlobalHooksTest
{
public class GlobalHooks
{
public delegate void HookReplacedEventHandler();
public delegate void WindowEventHandler(IntPtr Handle);
public delegate void SysCommandEventHandler(int SysCommand, int lParam);
public delegate void ActivateShellWindowEventHandler();
public delegate void TaskmanEventHandler();
public delegate void BasicHookEventHandler(IntPtr Handle1, IntPtr Handle2);
public delegate void WndProcEventHandler(IntPtr Handle, IntPtr Message, IntPtr wParam, IntPtr lParam);
// Functions imported from our unmanaged DLL
[DllImport("GlobalCbtHook.dll")]
private static extern bool InitializeCbtHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeCbtHook();
[DllImport("GlobalCbtHook.dll")]
private static extern bool InitializeShellHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeShellHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeKeyboardHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeKeyboardHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeMouseHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeMouseHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeKeyboardLLHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeKeyboardLLHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeMouseLLHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeMouseLLHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeCallWndProcHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeCallWndProcHook();
[DllImport("GlobalCbtHook.dll")]
private static extern void InitializeGetMsgHook(int threadID, IntPtr DestWindow);
[DllImport("GlobalCbtHook.dll")]
private static extern void UninitializeGetMsgHook();
// API call needed to retreive the value of the messages to intercept from the unmanaged DLL
[DllImport("user32.dll")]
private static extern int RegisterWindowMessage(string lpString);
[DllImport("user32.dll")]
private static extern IntPtr GetProp(IntPtr hWnd, string lpString);
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
// Handle of the window intercepting messages
private IntPtr _Handle;
private CBTHook _CBT;
private ShellHook _Shell;
private KeyboardHook _Keyboard;
private MouseHook _Mouse;
private KeyboardLLHook _KeyboardLL;
private MouseLLHook _MouseLL;
private CallWndProcHook _CallWndProc;
private GetMsgHook _GetMsg;
public GlobalHooks(IntPtr Handle)
{
_Handle = Handle;
_CBT = new CBTHook(_Handle);
_Shell = new ShellHook(_Handle);
_Keyboard = new KeyboardHook(_Handle);
_Mouse = new MouseHook(_Handle);
_KeyboardLL = new KeyboardLLHook(_Handle);
_MouseLL = new MouseLLHook(_Handle);
_CallWndProc = new CallWndProcHook(_Handle);
_GetMsg = new GetMsgHook(_Handle);
}
~GlobalHooks()
{
_CBT.Stop();
_Shell.Stop();
_Keyboard.Stop();
_Mouse.Stop();
_KeyboardLL.Stop();
_MouseLL.Stop();
_CallWndProc.Stop();
_GetMsg.Stop();
}
public void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
_CBT.ProcessWindowMessage(ref m);
_Shell.ProcessWindowMessage(ref m);
_Keyboard.ProcessWindowMessage(ref m);
_Mouse.ProcessWindowMessage(ref m);
_KeyboardLL.ProcessWindowMessage(ref m);
_MouseLL.ProcessWindowMessage(ref m);
_CallWndProc.ProcessWindowMessage(ref m);
_GetMsg.ProcessWindowMessage(ref m);
}
#region Accessors
public CBTHook CBT
{
get { return _CBT; }
}
public ShellHook Shell
{
get { return _Shell; }
}
public KeyboardHook Keyboard
{
get { return _Keyboard; }
}
public MouseHook Mouse
{
get { return _Mouse; }
}
public KeyboardLLHook KeyboardLL
{
get { return _KeyboardLL; }
}
public MouseLLHook MouseLL
{
get { return _MouseLL; }
}
public CallWndProcHook CallWndProc
{
get { return _CallWndProc; }
}
public GetMsgHook GetMsg
{
get { return _GetMsg; }
}
#endregion
public abstract class Hook
{
protected bool _IsActive = false;
protected IntPtr _Handle;
public Hook(IntPtr Handle)
{
_Handle = Handle;
}
public void Start()
{
if (!_IsActive)
{
_IsActive = true;
OnStart();
}
}
public void Stop()
{
if (_IsActive)
{
OnStop();
_IsActive = false;
}
}
~Hook()
{
Stop();
}
public bool IsActive
{
get { return _IsActive; }
}
protected abstract void OnStart();
protected abstract void OnStop();
public abstract void ProcessWindowMessage(ref System.Windows.Forms.Message m);
}
public class CBTHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_CBT_HookReplaced;
private int _MsgID_CBT_Activate;
private int _MsgID_CBT_CreateWnd;
private int _MsgID_CBT_DestroyWnd;
private int _MsgID_CBT_MinMax;
private int _MsgID_CBT_MoveSize;
private int _MsgID_CBT_SetFocus;
private int _MsgID_CBT_SysCommand;
public event HookReplacedEventHandler HookReplaced;
public event WindowEventHandler Activate;
public event WindowEventHandler CreateWindow;
public event WindowEventHandler DestroyWindow;
public event WindowEventHandler MinMax;
public event WindowEventHandler MoveSize;
public event WindowEventHandler SetFocus;
public event SysCommandEventHandler SysCommand;
public CBTHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_CBT_HookReplaced = RegisterWindowMessage("WILSON_HOOK_CBT_REPLACED");
_MsgID_CBT_Activate = RegisterWindowMessage("WILSON_HOOK_HCBT_ACTIVATE");
_MsgID_CBT_CreateWnd = RegisterWindowMessage("WILSON_HOOK_HCBT_CREATEWND");
_MsgID_CBT_DestroyWnd = RegisterWindowMessage("WILSON_HOOK_HCBT_DESTROYWND");
_MsgID_CBT_MinMax = RegisterWindowMessage("WILSON_HOOK_HCBT_MINMAX");
_MsgID_CBT_MoveSize = RegisterWindowMessage("WILSON_HOOK_HCBT_MOVESIZE");
_MsgID_CBT_SetFocus = RegisterWindowMessage("WILSON_HOOK_HCBT_SETFOCUS");
_MsgID_CBT_SysCommand = RegisterWindowMessage("WILSON_HOOK_HCBT_SYSCOMMAND");
// Start the hook
InitializeCbtHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeCbtHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_CBT_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
else if (m.Msg == _MsgID_CBT_Activate)
{
if (Activate != null)
Activate(m.WParam);
}
else if (m.Msg == _MsgID_CBT_CreateWnd)
{
if (CreateWindow != null)
CreateWindow(m.WParam);
}
else if (m.Msg == _MsgID_CBT_DestroyWnd)
{
if (DestroyWindow != null)
DestroyWindow(m.WParam);
}
else if (m.Msg == _MsgID_CBT_MinMax)
{
if (MinMax != null)
MinMax(m.WParam);
}
else if (m.Msg == _MsgID_CBT_MoveSize)
{
if (MoveSize != null)
MoveSize(m.WParam);
}
else if (m.Msg == _MsgID_CBT_SetFocus)
{
if (SetFocus != null)
SetFocus(m.WParam);
}
else if (m.Msg == _MsgID_CBT_SysCommand)
{
if (SysCommand != null)
SysCommand(m.WParam.ToInt32(), m.LParam.ToInt32());
}
}
}
public class ShellHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_Shell_ActivateShellWindow;
private int _MsgID_Shell_GetMinRect;
private int _MsgID_Shell_Language;
private int _MsgID_Shell_Redraw;
private int _MsgID_Shell_Taskman;
private int _MsgID_Shell_HookReplaced;
private int _MsgID_Shell_WindowActivated;
private int _MsgID_Shell_WindowCreated;
private int _MsgID_Shell_WindowDestroyed;
public event HookReplacedEventHandler HookReplaced;
public event ActivateShellWindowEventHandler ActivateShellWindow;
public event WindowEventHandler GetMinRect;
public event WindowEventHandler Language;
public event WindowEventHandler Redraw;
public event TaskmanEventHandler Taskman;
public event WindowEventHandler WindowActivated;
public event WindowEventHandler WindowCreated;
public event WindowEventHandler WindowDestroyed;
public ShellHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_Shell_HookReplaced = RegisterWindowMessage("WILSON_HOOK_SHELL_REPLACED");
_MsgID_Shell_ActivateShellWindow = RegisterWindowMessage("WILSON_HOOK_HSHELL_ACTIVATESHELLWINDOW");
_MsgID_Shell_GetMinRect = RegisterWindowMessage("WILSON_HOOK_HSHELL_GETMINRECT");
_MsgID_Shell_Language = RegisterWindowMessage("WILSON_HOOK_HSHELL_LANGUAGE");
_MsgID_Shell_Redraw = RegisterWindowMessage("WILSON_HOOK_HSHELL_REDRAW");
_MsgID_Shell_Taskman = RegisterWindowMessage("WILSON_HOOK_HSHELL_TASKMAN");
_MsgID_Shell_WindowActivated = RegisterWindowMessage("WILSON_HOOK_HSHELL_WINDOWACTIVATED");
_MsgID_Shell_WindowCreated = RegisterWindowMessage("WILSON_HOOK_HSHELL_WINDOWCREATED");
_MsgID_Shell_WindowDestroyed = RegisterWindowMessage("WILSON_HOOK_HSHELL_WINDOWDESTROYED");
// Start the hook
InitializeShellHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeShellHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_Shell_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
else if (m.Msg == _MsgID_Shell_ActivateShellWindow)
{
if (ActivateShellWindow != null)
ActivateShellWindow();
}
else if (m.Msg == _MsgID_Shell_GetMinRect)
{
if (GetMinRect != null)
GetMinRect(m.WParam);
}
else if (m.Msg == _MsgID_Shell_Language)
{
if (Language != null)
Language(m.WParam);
}
else if (m.Msg == _MsgID_Shell_Redraw)
{
if (Redraw != null)
Redraw(m.WParam);
}
else if (m.Msg == _MsgID_Shell_Taskman)
{
if (Taskman != null)
Taskman();
}
else if (m.Msg == _MsgID_Shell_WindowActivated)
{
if (WindowActivated != null)
WindowActivated(m.WParam);
}
else if (m.Msg == _MsgID_Shell_WindowCreated)
{
if (WindowCreated != null)
WindowCreated(m.WParam);
}
else if (m.Msg == _MsgID_Shell_WindowDestroyed)
{
if (WindowDestroyed != null)
WindowDestroyed(m.WParam);
}
}
}
public class KeyboardHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_Keyboard;
private int _MsgID_Keyboard_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event BasicHookEventHandler KeyboardEvent;
public KeyboardHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_Keyboard = RegisterWindowMessage("WILSON_HOOK_KEYBOARD");
_MsgID_Keyboard_HookReplaced = RegisterWindowMessage("WILSON_HOOK_KEYBOARD_REPLACED");
// Start the hook
InitializeKeyboardHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeKeyboardHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_Keyboard)
{
if (KeyboardEvent != null)
KeyboardEvent(m.WParam, m.LParam);
}
else if (m.Msg == _MsgID_Keyboard_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
public class MouseHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_Mouse;
private int _MsgID_Mouse_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event BasicHookEventHandler MouseEvent;
public MouseHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_Mouse = RegisterWindowMessage("WILSON_HOOK_MOUSE");
_MsgID_Mouse_HookReplaced = RegisterWindowMessage("WILSON_HOOK_MOUSE_REPLACED");
// Start the hook
InitializeMouseHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeMouseHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_Mouse)
{
if (MouseEvent != null)
MouseEvent(m.WParam, m.LParam);
}
else if (m.Msg == _MsgID_Mouse_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
public class KeyboardLLHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_KeyboardLL;
private int _MsgID_KeyboardLL_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event BasicHookEventHandler KeyboardLLEvent;
public KeyboardLLHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_KeyboardLL = RegisterWindowMessage("WILSON_HOOK_KEYBOARDLL");
_MsgID_KeyboardLL_HookReplaced = RegisterWindowMessage("WILSON_HOOK_KEYBOARDLL_REPLACED");
// Start the hook
InitializeKeyboardLLHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeKeyboardLLHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_KeyboardLL)
{
if (KeyboardLLEvent != null)
KeyboardLLEvent(m.WParam, m.LParam);
}
else if (m.Msg == _MsgID_KeyboardLL_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
public class MouseLLHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_MouseLL;
private int _MsgID_MouseLL_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event BasicHookEventHandler MouseLLEvent;
public event MouseEventHandler MouseDown;
public event MouseEventHandler MouseMove;
public event MouseEventHandler MouseUp;
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONUP = 0x0202;
private const int WM_LBUTTONDBLCLK = 0x0203;
private const int WM_RBUTTONDOWN = 0x0204;
private const int WM_RBUTTONUP = 0x0205;
private const int WM_RBUTTONDBLCLK = 0x0206;
private const int WM_MBUTTONDOWN = 0x0207;
private const int WM_MBUTTONUP = 0x0208;
private const int WM_MBUTTONDBLCLK = 0x0209;
private const int WM_MOUSEWHEEL = 0x020A;
struct MSLLHOOKSTRUCT
{
public System.Drawing.Point pt;
public int mouseData;
public int flags;
public int time;
public IntPtr dwExtraInfo;
};
public MouseLLHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_MouseLL = RegisterWindowMessage("WILSON_HOOK_MOUSELL");
_MsgID_MouseLL_HookReplaced = RegisterWindowMessage("WILSON_HOOK_MOUSELL_REPLACED");
// Start the hook
InitializeMouseLLHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeMouseLLHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_MouseLL)
{
if (MouseLLEvent != null)
MouseLLEvent(m.WParam, m.LParam);
MSLLHOOKSTRUCT M = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(m.LParam, typeof(MSLLHOOKSTRUCT));
if (m.WParam.ToInt32() == WM_MOUSEMOVE)
{
if (MouseMove != null)
MouseMove(this, new MouseEventArgs(MouseButtons.None, 0, M.pt.X, M.pt.Y, 0));
}
else if (m.WParam.ToInt32() == WM_LBUTTONDOWN)
{
if (MouseDown != null)
MouseDown(this, new MouseEventArgs(MouseButtons.Left, 0, M.pt.X, M.pt.Y, 0));
}
else if (m.WParam.ToInt32() == WM_RBUTTONDOWN)
{
if (MouseDown != null)
MouseDown(this, new MouseEventArgs(MouseButtons.Right, 0, M.pt.X, M.pt.Y, 0));
}
else if (m.WParam.ToInt32() == WM_LBUTTONUP)
{
if (MouseUp != null)
MouseUp(this, new MouseEventArgs(MouseButtons.Left, 0, M.pt.X, M.pt.Y, 0));
}
else if (m.WParam.ToInt32() == WM_RBUTTONUP)
{
if (MouseUp != null)
MouseUp(this, new MouseEventArgs(MouseButtons.Right, 0, M.pt.X, M.pt.Y, 0));
}
}
else if (m.Msg == _MsgID_MouseLL_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
public class CallWndProcHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_CallWndProc;
private int _MsgID_CallWndProc_Params;
private int _MsgID_CallWndProc_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event WndProcEventHandler CallWndProc;
private IntPtr _CacheHandle;
private IntPtr _CacheMessage;
public CallWndProcHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_CallWndProc_HookReplaced = RegisterWindowMessage("WILSON_HOOK_CALLWNDPROC_REPLACED");
_MsgID_CallWndProc = RegisterWindowMessage("WILSON_HOOK_CALLWNDPROC");
_MsgID_CallWndProc_Params = RegisterWindowMessage("WILSON_HOOK_CALLWNDPROC_PARAMS");
// Start the hook
InitializeCallWndProcHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeCallWndProcHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_CallWndProc)
{
_CacheHandle = m.WParam;
_CacheMessage = m.LParam;
}
else if (m.Msg == _MsgID_CallWndProc_Params)
{
if (CallWndProc != null && _CacheHandle != IntPtr.Zero && _CacheMessage != IntPtr.Zero)
CallWndProc(_CacheHandle, _CacheMessage, m.WParam, m.LParam);
_CacheHandle = IntPtr.Zero;
_CacheMessage = IntPtr.Zero;
}
else if (m.Msg == _MsgID_CallWndProc_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
public class GetMsgHook : Hook
{
// Values retreived with RegisterWindowMessage
private int _MsgID_GetMsg;
private int _MsgID_GetMsg_Params;
private int _MsgID_GetMsg_HookReplaced;
public event HookReplacedEventHandler HookReplaced;
public event WndProcEventHandler GetMsg;
private IntPtr _CacheHandle;
private IntPtr _CacheMessage;
public GetMsgHook(IntPtr Handle) : base(Handle)
{
}
protected override void OnStart()
{
// Retreive the message IDs that we'll look for in WndProc
_MsgID_GetMsg_HookReplaced = RegisterWindowMessage("WILSON_HOOK_GETMSG_REPLACED");
_MsgID_GetMsg = RegisterWindowMessage("WILSON_HOOK_GETMSG");
_MsgID_GetMsg_Params = RegisterWindowMessage("WILSON_HOOK_GETMSG_PARAMS");
// Start the hook
InitializeGetMsgHook(0, _Handle);
}
protected override void OnStop()
{
UninitializeGetMsgHook();
}
public override void ProcessWindowMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == _MsgID_GetMsg)
{
_CacheHandle = m.WParam;
_CacheMessage = m.LParam;
}
else if (m.Msg == _MsgID_GetMsg_Params)
{
if (GetMsg != null && _CacheHandle != IntPtr.Zero && _CacheMessage != IntPtr.Zero)
GetMsg(_CacheHandle, _CacheMessage, m.WParam, m.LParam);
_CacheHandle = IntPtr.Zero;
_CacheMessage = IntPtr.Zero;
}
else if (m.Msg == _MsgID_GetMsg_HookReplaced)
{
if (HookReplaced != null)
HookReplaced();
}
}
}
}
}