zoukankan      html  css  js  c++  java
  • winform键盘全局与线程Hook

    定义数据结构

            /// <summary>
            /// 声明键盘钩子的封送结构类型
            /// </summary>
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode;//表示一个1到254间的虚拟键盘码
                public int scanCode;//表示硬件扫描码
                public int flags;
                public int time;
                public int dwExtraInfo;
            }

    声明Hook相关方法

            //使用WINDOWS API函数代替获取当前实例的函数,防止钩子失效
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
            //安装钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
            //下一个钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
            //卸载钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
            // 取得当前线程编号(线程钩子需要用到)
            [DllImport("kernel32.dll")]
            static extern int GetCurrentThreadId();

    Hook拦截方法

    全局Hook

            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKBHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
     
                    //引发OnKeyDownEvent
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKBHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(keyData);
                        OnKeyDownEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }

    线程Hook

     private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                   
                    //引发OnKeyDownEvent
                    if (OnKeyDownEvent != null && nCode==0)
                    {
                        Keys keyData = (Keys)wParam;
                        KeyEventArgs e = new KeyEventArgs(keyData);
                        OnKeyDownEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }

    全局/线程Hook参数结构区别

    线程Hook KeyboardHookProc函数的各个参数意义如下:
    
    nCode    消息的类型,分HC_ACTION和HC_NOREMOVE
    
    wParam    按键的虚拟键码 
    
    lParam    按键的相关参数信息,包括重复时间、按键的状态(按下或弹起)等
    
    全局Hook KeyboardHookProc函数的各个参数意义如下:
    
    nCode    消息的类型,有HC_ACTION
    
    wParam    按键的状态(按下或弹起)WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP
    
    lParam    指向KeyboardHookStruct结构的指针,该结构包含了按键的详细信息。

    添加Hook

    全局Hook

            public void Start()
            {
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess())
                    using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule)
                        hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
     
                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("Set GlobalKeyboardHook failed!");
                    }
                }
            }

    线程Hook

       public void Start()
            {
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    hKeyboardHook = SetWindowsHookEx(2, KeyboardHookProcedure,  IntPtr.Zero, GetCurrentThreadId());
     
                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("Set GlobalKeyboardHook failed!");
                    }
                }
            }

    注:idHook 钩子类型,即确定钩子监听何种消息
    线程钩子监听键盘消息应设为2,全局钩子监听键盘消息应设为13
    线程钩子监听鼠标消息应设为7,全局钩子监听鼠标消息应设为14

  • 相关阅读:
    金融系列7《动态数据认证》
    PHP异常处理详解
    C语言中的宏定义
    PHP SOCKET编程
    yii实现级联下拉菜单
    AR的一些常见的操作
    IP地址的三种表示格式及在Socket编程中的应用
    时间管理
    socket阻塞与非阻塞,同步与异步、I/O模型
    程序人生 PHP工程师
  • 原文地址:https://www.cnblogs.com/yanpeng19940119/p/14598848.html
Copyright © 2011-2022 走看看