我发现并不总是调用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;
};
答案 0 :(得分:10)
区别在于调用回调时的行为。 如果您使用的是低级版本,则不会因为执行对钩子函数的调用而导致lpfn带来的限制。请阅读下面的更多信息。 引自MSDN的SetWindowsHookEx文档:
lpfn [in]指向钩子程序的指针。如果dwThreadId参数为零或指定由其他进程创建的线程的标识符,则lpfn参数必须指向DLL中的挂钩过程。否则,lpfn可以指向与当前进程关联的代码中的钩子过程。
并从LowLevelKeyboardProc:
WH_KEYBOARD_LL挂钩不会注入另一个进程。相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它。然后上下文切换回生成事件的应用程序。