2017-04-03 70 views
2

我想问一个关于我遇到的问题的问题。MouseProc(WH_MOUSE)事件触发两次

我使用下面的函数安装WH_MOUSE钩:

hMouseHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, dllInstance, threadId); 

线程ID使用GetWindowThreadProcessId函数被获得。这是成功的,因为钩子只在我想要的过程中起作用。 dllInstanceDllMain入口点获得。对于它的价值,hMouseHook位于共享数据段(#pragma data_seg(“。shared”))。下面的代码示出了MouseHookProc即在上述调用SetWindowsHookEx呼叫提供:

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { 
    if (nCode < 0 || !isRunning()) 
     return CallNextHookEx(hMouseHook, nCode, wParam, lParam); 

    switch (wParam) { 
     case WM_LBUTTONDOWN: { 
      OutputDebugStringA("Mouse button down!\n"); 
      break; 
     } 
    } 

    return CallNextHookEx(hMouseHook, nCode, wParam, lParam); 
} 

测试时,isRunning()返回TRUE(I双重检查)。我的问题是,“鼠标按钮按下!”每次按住鼠标左键时,消息将被打印两次。为什么根据提供的代码,这是否会发生?我目前正在使用一种解决方法,但想知道为什么会发生这种情况。

我在Visual Studio 2015中调试启动程序(调用DLL的函数包含SetWindowsHookEx)并将其附加到我正在使用的进程(调试 - >附加到进程)。

在此先感谢您的回复。

编辑:它似乎只有第一次调用nCode == HC_ACTION的过程。我想这是对我的问题的答案,但我想知道为什么我的过程与nCode == HC_NOREMOVE第二次调用?

+0

我的期望是'HC_NOREMOVE'调用('PeekMessage'调用'PM_NOREMOVE')是第一个。我不知道为什么这是第二个电话。您可以忽略使用“HC_NOREMOVE”标志的任何调用。 – 1201ProgramAlarm

+0

这是完全正常的和[记录的行为](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644988(v = vs.85).aspx)。 –

+0

@ 1201ProgramAlarm其实,我只是可惜地认为它是第二,没有检查。你是对的,HC_NOREMOVE是第一个。现在我的问题仍然存在,为什么用HC_NOREMOVE消息调用我的过程?这段代码的目的是什么? –

回答

0

用nCode == HC_NOREMOVE调用一次,然后再用nCode == HC_ACTION调用。