tags:

views:

796

answers:

1

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;
};
+2  A: 

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.
emaster70
Do I understand correctly: if I'm using a WH_MOUSE hook, it must be implemented in a DLL?
Alex Jenter
Only if you want to use that hook to catch events from processes other than that calling SetWindowsHookEx
emaster70
Ok it's clear now, thank you very much!
Alex Jenter