WH_MOUSE和WH_MOUSE_LL钩子之间有什么区别?

时间:2009-05-16 15:53:07

标签: c++ winapi hook

我发现并不总是调用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;
};

1 个答案:

答案 0 :(得分:10)

区别在于调用回调时的行为。 如果您使用的是低级版本,则不会因为执行对钩子函数的调用而导致lpfn带来的限制。请阅读下面的更多信息。 引自MSDN的SetWindowsHookEx文档:

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

并从LowLevelKeyboardProc:

WH_KEYBOARD_LL挂钩不会注入另一个进程。相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它。然后上下文切换回生成事件的应用程序。