Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are all the differences between WH_MOUSE and WH_MOUSE_LL hooks?

Tags:

c++

winapi

hook

I've found that WH_MOUSE is not always called. Could the problem be that I'm using WH_MOUSE and not WH_MOUSE_LL?

The code:

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;
};
like image 595
Alex Jenter Avatar asked May 16 '09 15:05

Alex Jenter


1 Answers

The difference is in the behavior when the callback gets called. If you're using the lowlevel version you don't incur in the limitations posed by lpfn because of the way the call to your hook function is performed. Please read below for more information. Quoting from MSDN's doc for SetWindowsHookEx:

lpfn [in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a DLL. Otherwise, lpfn can point to a hook procedure in the code associated with the current process.

and from LowLevelKeyboardProc:

the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
like image 146
em70 Avatar answered Oct 19 '22 22:10

em70