Skip to content

Instantly share code, notes, and snippets.

@pigeonhands
Last active August 1, 2019 19:44
Show Gist options
  • Save pigeonhands/35dbd09b1a4ffe7193e1 to your computer and use it in GitHub Desktop.
Save pigeonhands/35dbd09b1a4ffe7193e1 to your computer and use it in GitHub Desktop.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
/// <summary>
/// Low Level mouse and keyboard hook wrapper
/// Made by BahNahNah
/// </summary>
public class LowLevelHook
{
#region " Delegates "
private delegate IntPtr LowLevelHookCallback(int nCode, IntPtr wParam, IntPtr lParam);
public delegate void LLKeyboardHook(string hKey, LowLevelKeyboardParameter parameter);
public delegate void LLMouseHook(LowLevelMouseButtons button, LLMouseLocation location);
#endregion
#region " Events "
public static event LLKeyboardHook KeyboardEvent;
public static event LLMouseHook MouseEvent;
#endregion
#region " Values "
private static bool LShiftPress = false;
private static bool RShiftPress = false;
private static bool CapsPressed = false;
static LowLevelHookCallback KBCallback = new LowLevelHookCallback(LLKeyboardCallback);
static LowLevelHookCallback MCallback = new LowLevelHookCallback(LLMouseCallback);
#endregion
#region " Hooks "
static IntPtr KBHook = IntPtr.Zero;
static IntPtr MHook = IntPtr.Zero;
#endregion
#region " Functions "
/// <summary>
/// Apply Low level hook to keyboard
/// </summary>
public static void HookKeyboard()
{
if (KBHook != IntPtr.Zero)
throw new Exception("Keyboard is alredy hooked.");
KBHook = SetWindowsHookEx(13, KBCallback, IntPtr.Zero, 0);
}
/// <summary>
/// Apply Low level hook to mouse
/// </summary>
public static void HookMouse()
{
if (MHook != IntPtr.Zero)
throw new Exception("Keyboard is alredy hooked.");
MHook = SetWindowsHookEx(14, MCallback, IntPtr.Zero, 0);
}
/// <summary>
/// Remove low level hook from keyboard
/// </summary>
public static void UnhookKeyboard()
{
if (UnhookWindowsHookEx(KBHook))
KBHook = IntPtr.Zero;
}
/// <summary>
/// Remove low level hook from mouse
/// </summary>
public static void UnhookMouse()
{
if (UnhookWindowsHookEx(MHook))
MHook = IntPtr.Zero;
}
#endregion
#region " Callbacks "
private static IntPtr LLKeyboardCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode > -1 && KeyboardEvent != null)
{
LLKeyboardHook call = KeyboardEvent;
LowLevelKeyboardParameter p = (LowLevelKeyboardParameter)wParam;
Keys key = (Keys)Marshal.ReadInt32(lParam);
if (key == Keys.LShiftKey) LShiftPress = (p == LowLevelKeyboardParameter.KeyDown);
if (key == Keys.RShiftKey) RShiftPress = (p == LowLevelKeyboardParameter.KeyDown);
if (key == Keys.CapsLock) CapsPressed = (p == LowLevelKeyboardParameter.KeyDown);
string v = (LShiftPress || RShiftPress || CapsPressed) ? key.ToString() : key.ToString().ToLower();
call(v, p);
}
return CallNextHookEx(KBHook, nCode, wParam, lParam);
}
private static IntPtr LLMouseCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode > -1 && MouseEvent != null)
{
LLMouseHook call = MouseEvent;
LowLevelMouseButtons b = (LowLevelMouseButtons)wParam;
LLMouseLocation location = (LLMouseLocation)Marshal.PtrToStructure(lParam, typeof(LLMouseLocation));
call(b, location);
}
return CallNextHookEx(KBHook, nCode, wParam, lParam);
}
#endregion
#region " WinApi "
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelHookCallback lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern int ToUnicodeEx(uint key, uint scancode, byte[] keyState, StringBuilder buffer, int bufferSuise, uint flags, IntPtr kblout);
[DllImport("user32.dll")]
private static extern bool GetKeyboardState(byte[] buffer);
[DllImport("user32.dll")]
private static extern int GetAsyncKeyState(int vkCode);
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint idThread);
#endregion
}
public enum LowLevelKeyboardParameter
{
KeyDown = 0x100,
KeyUp = 0x101,
SysKeyDown = 0x104,
SysKeyUp = 0x105
}
public enum LowLevelMouseButtons
{
MOVE = 0x200,
LDOWN = 0x201,
LUP = 0x202,
RDOWN = 0x204,
RUP = 0x205,
MWheel = 0x20A,
MHWheel = 0x20E
}
public struct LLMouseLocation
{
int _X;
int _Y;
public int X { get { return _X; } }
public int Y { get { return _Y; } }
public override string ToString()
{
return string.Format("({0},{1})", X, Y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment