7

我发现WH_MOUSE并不总是这样。问题可能是我正在使用WH_MOUSE而不是WH_MOUSE_LL

编码:

class MouseHook
{
public:
  static signal<void(UINT, const MOUSEHOOKSTRUCT&)> clickEvent;

  static bool install() 
  {
    if (isInstalled()) return true;
    hook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)&mouseProc,  
                                ::GetModuleHandle(NULL), NULL);
    return(hook != NULL);
  }

  static bool uninstall() 
  {
    if (hook == NULL) return TRUE;
    bool fOk = ::UnhookWindowsHookEx(hook);
    hook = NULL;
    return fOk != FALSE;
  }

  static bool isInstalled() { return hook != NULL; }

private:
   static LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam)
   {            
      if (nCode == HC_ACTION && 
        (wParam == WM_LBUTTONDOWN || wParam == WM_NCLBUTTONDOWN ||
         wParam == WM_RBUTTONDOWN || wParam == WM_NCRBUTTONDOWN ||
         wParam == WM_MBUTTONDOWN || wParam == WM_NCMBUTTONDOWN ))
      {
        MOUSEHOOKSTRUCT* mhs = (MOUSEHOOKSTRUCT*) lParam;
        clickEvent(wParam, *mhs);
      }         

      return ::CallNextHookEx(hook, nCode, wParam, lParam);
    }

   static HHOOK hook;
};
4

1 回答 1

11

不同之处在于回调被调用时的行为。如果您使用的是低级版本,则不会因为调用钩子函数的方式而受到 lpfn 带来的限制。请阅读以下内容以获取更多信息。引用 MSDN 的 SetWindowsHookEx 文档:

lpfn [in] 指向钩子程序的指针。如果 dwThreadId 参数为零或指定由不同进程创建的线程的标识符,则 lpfn 参数必须指向 DLL 中的挂钩过程。否则,lpfn 可以指向与当前进程关联的代码中的挂钩过程。

并来自 LowLevelKeyboardProc:

WH_KEYBOARD_LL 钩子没有注入到另一个进程中。相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它。然后上下文切换回生成事件的应用程序。
于 2009-05-16T16:13:06.470 回答