代码之家  ›  专栏  ›  技术社区  ›  Nippysaurus

SetWindowsHookEx键盘将不会获取事件

  •  0
  • Nippysaurus  · 技术社区  · 15 年前

    我正在使用SetWindowsHookEx()创建键盘挂钩。创建似乎是成功的,但注册的过程从未被调用。我做错什么了吗?

    #region Windows API Functions Declarations
    
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(int idHook);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
    
    #endregion
    

    =

    private void CreateHook()
    {
       int id_hook = (int)HookType.WH_KEYBOARD_LL;
       HookProc lpfn = new HookProc(this.KeyboardHookProc);
    
       using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
          hHook = SetWindowsHookEx(id_hook, lpfn, GetModuleHandle(curModule.ModuleName), 0);
    
       if (hHook == 0)
          throw new Exception("could not start monitoring mouse events");
    }
    

    =

    private int KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam)
    {
       if (code >= 0)
          Console.WriteLine((Keys)wParam.ToInt32());
       return CallNextHookEx(0, code, wParam, lParam);
    }
    

    =

    1 回复  |  直到 15 年前
        1
  •  6
  •   Hans Passant    15 年前

    您的P/Invoke声明是错误的,您在需要IntPtr的地方使用int,并且混淆了idHook和hHook。在编辑代码后,这一点起到了作用:

    IntPtr hHook;
    private delegate IntPtr HookProc(int nCode, IntPtr wp, IntPtr lp);
    HookProc lpfn;
    
    private IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam) {
      if (code >= 0)
        Console.WriteLine((Keys)wParam.ToInt32());
      return CallNextHookEx(hHook, code, wParam, lParam);
    }
    
    private void CreateHook() {
      int id_hook = 13;
      lpfn = new HookProc(this.KeyboardHookProc);
      using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
        hHook = SetWindowsHookEx(id_hook, lpfn, GetModuleHandle(curModule.ModuleName), 0);
      if (hHook == IntPtr.Zero)
        throw new Exception("could not start monitoring mouse events");
    }
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(IntPtr hHook);
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
    
    推荐文章