NativeMethods.cs:
using System; using System.Runtime.InteropServices; namespace GlobalHook { internal static class NativeMethods { #region window message internal const int WM_MOUSEMOVE = 0x200; internal const int WM_LBUTTONDOWN = 0x201; internal const int WM_RBUTTONDOWN = 0x204; internal const int WM_MBUTTONDOWN = 0x207; internal const int WM_LBUTTONUP = 0x202; internal const int WM_RBUTTONUP = 0x205; internal const int WM_MBUTTONUP = 0x208; internal const int WM_LBUTTONDBLCLK = 0x203; internal const int WM_RBUTTONDBLCLK = 0x206; internal const int WM_MBUTTONDBLCLK = 0x209; internal const int WM_MOUSEWHEEL = 0x020A; #endregion #region param idHook internal const int WH_CALLWNDPROC = 4; internal const int WH_CALLWNDPROCRET = 12; internal const int WH_CBT = 5; internal const int WH_DEBUG = 9; internal const int WH_FOREGROUNDIDLE = 11; internal const int WH_GETMESSAGE = 3; internal const int WH_JOURNALPLAYBACK = 1; internal const int WH_JOURNALRECORD = 0; internal const int WH_KEYBOARD = 2; internal const int WH_KEYBOARD_LL = 13; internal const int WH_MOUSE = 7; internal const int WH_MOUSE_LL = 14; internal const int WH_MSGFILTER = -1; internal const int WH_SHELL = 10; internal const int WH_SYSMSGFILTER = 6; #endregion [StructLayout(LayoutKind.Sequential)] internal class POINT { internal int x; internal int y; internal POINT(int x, int y) { this.x = x; this.y = y; } } [StructLayout(LayoutKind.Sequential)] internal class MOUSEHOOKSTRUCT { internal POINT pt; internal IntPtr hWnd; internal int wHitTestCode; internal int dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] internal class MOUSEHOOKSTRUCTEX { internal MOUSEHOOKSTRUCT MOUSEHOOKSTRUCT; internal uint mouseData; } internal delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); } }
UnsafeNativeMethods.cs:
using System; using System.Runtime.InteropServices; using static GlobalHook.NativeMethods; namespace GlobalHook { internal static class UnsafeNativeMethods { /// <summary> /// https://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx
/// </summary> /// <param name="idHook"></param> /// <param name="lpfn"></param> /// <param name="hMod"></param> /// <param name="dwThreadId"></param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] internal static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, HandleRef hMod, int dwThreadId); /// <summary> /// https://msdn.microsoft.com/en-us/library/ms644993(VS.85).aspx
/// </summary> /// <param name="hhk"></param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] internal static extern bool UnhookWindowsHookEx(HandleRef hhk); /// <summary> /// https://msdn.microsoft.com/en-us/library/ms644974(VS.85).aspx
/// </summary> /// <param name="hhk"></param> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] internal static extern IntPtr CallNextHookEx(HandleRef hhk, int nCode, IntPtr wParam, IntPtr lParam); /// <summary> /// https://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx
/// </summary> /// <param name="lpModuleName"></param> /// <returns></returns> [DllImport("kernel32.dll", CharSet = CharSet.Auto)] internal static extern IntPtr GetModuleHandle(string lpModuleName); } }
From1.cs:
using System; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using static GlobalHook.NativeMethods; using static GlobalHook.SafeNativeMethods; using static GlobalHook.UnsafeNativeMethods; namespace GlobalHook { public partial class Form1 : Form { private IntPtr hook; private HookProc mouseHookProcedure; public Form1() { InitializeComponent(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { UnhookWindowsHookEx(new HandleRef(null, hook)); } private void btnHook_Click(object sender, EventArgs e) { if (btnHook.Text == "hook") { mouseHookProcedure = LowLevelMouseProc; hook = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProcedure, new HandleRef(null, GetModuleHandle(null)), 0); if (hook != IntPtr.Zero)
{ btnHook.Text = "unhook";
} } else { if (UnhookWindowsHookEx(new HandleRef(null, hook))) { btnHook.Text = "hook"; } } } private IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam) { MOUSEHOOKSTRUCT mouseHookStruct = Marshal.PtrToStructure<MOUSEHOOKSTRUCT>(lParam); switch ((int)wParam) { case WM_MOUSEMOVE: break; case WM_LBUTTONDOWN: break; case WM_RBUTTONDOWN: break; case WM_MBUTTONDOWN: break; case WM_LBUTTONUP: break; case WM_RBUTTONUP: break; case WM_MBUTTONUP: break; case WM_LBUTTONDBLCLK: break; case WM_RBUTTONDBLCLK: break; case WM_MBUTTONDBLCLK: break; case WM_MOUSEWHEEL: break; default: break; } return CallNextHookEx(new HandleRef(null, hook), nCode, wParam, lParam); } } }