public class Hook
{
public delegate int HookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam);
public enum WH_CODE : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
/// <summary>
/// 进程钩子
/// </summary>
WH_KEYBOARD = 2,
/// <summary>
/// 底层键盘钩子 全局钩子就是用这个
/// </summary>
WH_KEYBOARD_LL = 13,
}
public enum HC_CODE : int
{
HC_ACTION = 0,
HC_GETNEXT = 1,
HC_SKIP = 2,
HC_NOREMOVE = 3,
HC_NOREM = 3,
HC_SYSMODALON = 4,
HC_SYSMODALOFF = 5
}
/// <summary>
/// 安装钩子
/// </summary>
[DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SetWindowsHookEx(WH_CODE idHook, HookProc lpfn, IntPtr pInstance, uint threadId);
/// <summary>
/// 卸载钩子
/// </summary>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
/// <summary>
/// 传递钩子
/// </summary>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(IntPtr pHookHandle, WH_CODE nCodem, Int32 wParam, IntPtr lParam);
/// <summary>
/// 获取全部按键状态
/// </summary>
/// <param name="pbKeyState"></param>
/// <returns>非0表示成功</returns>
[DllImport("user32.dll")]
public static extern int GetKeyboardState(byte[] pbKeyState);
/// <summary>
/// 获取程序集模块的句柄
/// </summary>
/// <param name="lpModuleName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
/// <summary>
/// 获取当前进程中的当前线程ID
/// </summary>
/// <returns></returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern uint GetCurrentThreadId();
#region 私有变量
private byte[] mKeyState = new byte[256];
private Keys mKeyData = Keys.None; //专门用于判断按键的状态
/// <summary>
/// 键盘钩子句柄
/// </summary>
private IntPtr mKetboardHook = IntPtr.Zero;
/// <summary>
/// 键盘钩子委托实例
/// </summary>
private HookProc mKeyboardHookProcedure;
#endregion
#region 键盘事件
public List<TypeStatus> list = null;
public event Action OnDKeyDown;
public event Action OnAKeyDown;
public event Action OnWKeyDown;
public event Action OnBKeyDown;
public event Action OnCKeyDown;
public event Action OnFKeyDown;
public event Action OnSKeyDown;
public event Action OnDeleteKeyDown;
public event Action OnOKeyDown;
public event Action OnUpDown;
public event Action OnDownDown;
public event Action OnRightDown;
public event Action OnLeftDown;
public event Action<string> OnEverDown;
public bool FormStatus = true;
#endregion
/// <summary>
/// 构造函数
/// </summary>
public Hook()
{
GetKeyboardState(this.mKeyState);
}
~Hook()
{
UnInstallHook();
}
bool KeyDown = true;
/// <summary>
/// 键盘钩子处理函数
/// </summary>
private int KeyboardHookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam)
{
/*全局钩子应该这样设定
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
*/
// 定义为线程钩子时,wParam的值是击打的按键,与Keys里的对应按键相同
if (((int)nCode == (int)HC_CODE.HC_NOREMOVE))
{
if (FormStatus)
{
mKeyData = (Keys)wParam;
KeyEventArgs keyEvent = new KeyEventArgs(mKeyData);
if (lParam.ToInt32() < 0) { KeyDown = true; Console.WriteLine("松开一个键了"); };
if (lParam.ToInt32() > 0) {
if (mKeyData == Keys.Up && lParam.ToInt32() > 0)
{
this.OnUpDown();
}
if (mKeyData == Keys.Down && lParam.ToInt32() > 0)
{
this.OnDownDown();
}
if (mKeyData == Keys.Right && lParam.ToInt32() > 0)
{
this.OnRightDown();
}
if (mKeyData == Keys.Left && lParam.ToInt32() > 0)
{
Console.WriteLine("111111111111111111111");
this.OnLeftDown();
}
}
if (KeyDown && lParam.ToInt32() > 0)
{
//这里简单的通过lParam的值的正负情况与按键的状态相关联
if (mKeyData == Keys.D && lParam.ToInt32() > 0)
{
this.OnDKeyDown();
}
if (mKeyData == Keys.A && lParam.ToInt32() > 0)
{
Console.WriteLine("按下A键" + DateTime.Now.ToString() + "-------------------------");
this.OnAKeyDown();
}
if (mKeyData == Keys.B && lParam.ToInt32() > 0)
{
this.OnBKeyDown();
}
if (mKeyData == Keys.C && lParam.ToInt32() > 0)
{
this.OnCKeyDown();
}
if (mKeyData == Keys.W && lParam.ToInt32() > 0)
{
this.OnWKeyDown();
}
if (mKeyData == Keys.F && lParam.ToInt32() > 0)
{
this.OnFKeyDown();
}
if (mKeyData == Keys.S && lParam.ToInt32() > 0)
{
this.OnSKeyDown();
}
if (mKeyData == Keys.Delete && lParam.ToInt32() > 0)
{
this.OnDeleteKeyDown();
}
if (mKeyData == Keys.Oem3 && lParam.ToInt32() > 0)
{
Console.WriteLine("按下~键" + DateTime.Now.ToString());
this.OnOKeyDown();
}
if (list != null && lParam.ToInt32() > 0)
{
var num = list.Where(n => (n.Kurrtnum == ((int)mKeyData).ToString() || n.Kurrt == mKeyData.ToString().ToLower()) && n.Status == true && n.Kurrt != "").FirstOrDefault();
if (num != null)
{
this.OnEverDown(num.Name);
}
}
KeyDown = false;
}
}
}
return CallNextHookEx(this.mKetboardHook, nCode, wParam, lParam);
}
/// <summary>
/// 安装钩子
/// </summary>
/// <returns></returns>
public bool InstallHook()
{
//线程钩子时一定要通过这个取得的值才是操作系统下真实的线程
uint result = GetCurrentThreadId();
if (this.mKetboardHook == IntPtr.Zero)
{
this.mKeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
//注册线程钩子时第三个参数是空
this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD, this.mKeyboardHookProcedure, IntPtr.Zero, result);
/*
如果是全局钩子应该这样使用
this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD_LL, mKeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
*/
if (this.mKetboardHook == IntPtr.Zero)
{
return false;
}
}
return true;
}
/// <summary>
/// 卸载钩子
/// </summary>
/// <returns>true表示成功 </returns>
public bool UnInstallHook()
{
bool result = true;
if (this.mKetboardHook != IntPtr.Zero)
{
result = UnhookWindowsHookEx(this.mKetboardHook) && result;
this.mKetboardHook = IntPtr.Zero;
}
return result;
}
}