csharp 全局键盘鼠标钩子
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 全局键盘鼠标钩子相关的知识,希望对你有一定的参考价值。
internal class MouseHookHelper
{
#region PInvoke
private enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
private struct POINT
{
public int x;
public int y;
}
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public int mouseData;
public UInt32 flags;
public UInt32 time;
public IntPtr dwExtraInfo;
}
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, IntPtr lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
#endregion PInvoke
public delegate void MouseEventDelegate(MouseHookEventArgs e);
public event MouseEventDelegate MouseDownEvent;
public event MouseEventDelegate MouseUpEvent;
public event MouseEventDelegate MouseMoveEvent;
public event MouseEventDelegate MouseWheelEvent;
public delegate void KeyUpEventDelegate(MouseHookEventArgs e);
private HookProc _hookproc;
private IntPtr _hhook;
public void StartHook()
{
_hookproc = new HookProc(HookCallback);
_hhook = SetWindowsHookEx((int)HookType.WH_MOUSE_LL, Marshal.GetFunctionPointerForDelegate(_hookproc), GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
if (_hhook == null || _hhook == IntPtr.Zero)
{
Win32Exception LastError = new Win32Exception(Marshal.GetLastWin32Error());
}
}
public void StopHook()
{
if (_hhook != IntPtr.Zero)
{
UnhookWindowsHookEx(_hhook);
}
}
private int HookCallback(int code, IntPtr wParam, IntPtr lParam)
{
int result = 0;
MouseHookEventArgs args = null;
try
{
if (code >= 0)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var button = MouseButtons.None;
if (wParam.ToInt32() == (int)MouseMessages.WM_LBUTTONDOWN || wParam.ToInt32() == (int)MouseMessages.WM_LBUTTONUP)
{
button = MouseButtons.Left;
}
if (wParam.ToInt32() == (int)MouseMessages.WM_RBUTTONDOWN || wParam.ToInt32() == (int)MouseMessages.WM_RBUTTONUP)
{
button = MouseButtons.Right;
}
args = new MouseHookEventArgs(button, hookStruct.pt.x, hookStruct.pt.y, hookStruct.mouseData, hookStruct.flags, hookStruct.time, hookStruct.dwExtraInfo);
if (wParam.ToInt32() == (int)MouseMessages.WM_LBUTTONDOWN || wParam.ToInt32() == (int)MouseMessages.WM_RBUTTONDOWN)
{
MouseDownEvent?.Invoke(args);
}
if (wParam.ToInt32() == (int)MouseMessages.WM_LBUTTONUP || wParam.ToInt32() == (int)MouseMessages.WM_RBUTTONUP)
{
MouseUpEvent?.Invoke(args);
}
if (wParam.ToInt32() == (int)MouseMessages.WM_MOUSEMOVE)
{
MouseMoveEvent?.Invoke(args);
}
if (wParam.ToInt32() == (int)MouseMessages.WM_MOUSEWHEEL)
{
MouseWheelEvent?.Invoke(args);
}
}
}
finally
{
result = CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
if (args != null && args.Cancel)
{
return 1;
}
else
{
return result;
}
}
}
internal class MouseHookEventArgs : CancelEventArgs
{
public MouseButtons Button { get; private set; }
public int X { get; private set; }
public int Y { get; private set; }
public int Delta { get; private set; }
public IntPtr ExtraInfo { get; private set; }
internal MouseHookEventArgs(MouseButtons button, int x, int y, int mouseData, UInt32 flags, UInt32 time, IntPtr dwExtraInfo)
{
Button = button;
X = x;
Y = y;
Delta = mouseData;
ExtraInfo = dwExtraInfo;
}
public override string ToString()
{
return string.Format("Button={0}; X={1}; Y={2}; Delta={3}", new object[] { Button, X, Y, Delta });
}
}
internal class KeyboardHookHelper
{
#region PInvoke
private enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
private struct KBDLLHOOKSTRUCT
{
public UInt32 vkCode;
public UInt32 scanCode;
public UInt32 flags;
public UInt32 time;
public IntPtr extraInfo;
}
private enum KeyboardMessages
{
WM_KEYDOWN = 0x100,
WM_KEYUP = 0x101,
WM_SYSKEYDOWN = 0x0104,
WM_SYSKEYUP = 0x105
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, IntPtr lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private delegate int LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
#endregion PInvoke
public delegate void KeyboardEventDelegate(KeyboardHookEventArgs e);
public event KeyboardEventDelegate KeyDownEvent;
public event KeyboardEventDelegate KeyUpEvent;
private LowLevelKeyboardProc _hookproc;
private IntPtr _hhook;
public void StartHook()
{
_hookproc = new LowLevelKeyboardProc(HookCallback);
_hhook = SetWindowsHookEx((int)HookType.WH_KEYBOARD_LL, Marshal.GetFunctionPointerForDelegate(_hookproc), GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
if (_hhook == null || _hhook == IntPtr.Zero)
{
Win32Exception LastError = new Win32Exception(Marshal.GetLastWin32Error());
}
}
public void StopHook()
{
if (_hhook != IntPtr.Zero)
{
UnhookWindowsHookEx(_hhook);
}
}
private int HookCallback(int code, IntPtr wParam, IntPtr lParam)
{
int result = 0;
KeyboardHookEventArgs args = null;
try
{
if (code >= 0)
{
KBDLLHOOKSTRUCT hookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
args = new KeyboardHookEventArgs(hookStruct.vkCode, hookStruct.scanCode, hookStruct.flags, hookStruct.time, hookStruct.extraInfo);
if (wParam.ToInt32() == (int)KeyboardMessages.WM_SYSKEYDOWN || wParam.ToInt32() == (int)KeyboardMessages.WM_KEYDOWN)
{
KeyDownEvent?.Invoke(args);
}
if (wParam.ToInt32() == (int)KeyboardMessages.WM_SYSKEYUP || wParam.ToInt32() == (int)KeyboardMessages.WM_KEYUP)
{
KeyUpEvent?.Invoke(args);
}
}
}
finally
{
result = CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
if (args != null && args.Cancel)
{
return 1;
}
else
{
return result;
}
}
}
internal class KeyboardHookEventArgs : CancelEventArgs
{
#region PInvoke
[DllImport("user32.dll")]
private static extern short GetKeyState(VirtualKeyStates nVirtKey);
private enum VirtualKeyStates : int
{
VK_LWIN = 0x5B,
VK_RWIN = 0x5C,
VK_LSHIFT = 0xA0,
VK_RSHIFT = 0xA1,
VK_LCONTROL = 0xA2,
VK_RCONTROL = 0xA3,
VK_LALT = 0xA4, //aka VK_LMENU
VK_RALT = 0xA5, //aka VK_RMENU
}
private const int KEY_PRESSED = 0x8000;
#endregion PInvoke
public Keys Key { get; private set; }
public IntPtr ExtraInfo { get; private set; }
public bool isAltPressed { get { return isLAltPressed || isRAltPressed; } }
public bool isLAltPressed { get; private set; }
public bool isRAltPressed { get; private set; }
public bool isCtrlPressed { get { return isLCtrlPressed || isRCtrlPressed; } }
public bool isLCtrlPressed { get; private set; }
public bool isRCtrlPressed { get; private set; }
public bool isShiftPressed { get { return isLShiftPressed || isRShiftPressed; } }
public bool isLShiftPressed { get; private set; }
public bool isRShiftPressed { get; private set; }
public bool isWinPressed { get { return isLWinPressed || isRWinPressed; } }
public bool isLWinPressed { get; private set; }
public bool isRWinPressed { get; private set; }
internal KeyboardHookEventArgs(UInt32 vkCode, UInt32 scanCode, UInt32 flags, UInt32 time, IntPtr dwExtraInfo)
{
Key = (Keys)vkCode;
ExtraInfo = dwExtraInfo;
//Control.ModifierKeys doesn't capture alt/win, and doesn't have r/l granularity
this.isLAltPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_LALT) & KEY_PRESSED) || this.Key == Keys.LMenu;
this.isRAltPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_RALT) & KEY_PRESSED) || this.Key == Keys.RMenu;
this.isLCtrlPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_LCONTROL) & KEY_PRESSED) || this.Key == Keys.LControlKey;
this.isRCtrlPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_RCONTROL) & KEY_PRESSED) || this.Key == Keys.RControlKey;
this.isLShiftPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_LSHIFT) & KEY_PRESSED) || this.Key == Keys.LShiftKey;
this.isRShiftPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_RSHIFT) & KEY_PRESSED) || this.Key == Keys.RShiftKey;
this.isLWinPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_LWIN) & KEY_PRESSED) || this.Key == Keys.LWin;
this.isRWinPressed = Convert.ToBoolean(GetKeyState(VirtualKeyStates.VK_RWIN) & KEY_PRESSED) || this.Key == Keys.RWin;
if (this.Key == Keys.LMenu || this.Key == Keys.RMenu)
{
this.Key = Keys.Menu;
}
if (this.Key == Keys.LControlKey || this.Key == Keys.RControlKey)
{
this.Key = Keys.ControlKey;
}
if (this.Key == Keys.LShiftKey || this.Key == Keys.RShiftKey)
{
this.Key = Keys.ShiftKey;
}
}
public override string ToString()
{
return string.Format("Key={0}; Win={1}; Alt={2}; Ctrl={3}; Shift={4}", new object[] { Key, isWinPressed, isAltPressed, isCtrlPressed, isShiftPressed });
}
}
以上是关于csharp 全局键盘鼠标钩子的主要内容,如果未能解决你的问题,请参考以下文章