C# 键盘线程钩子

  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;
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_38341160/article/details/115348234