MouseProc (WH_MOUSE) 事件触发两次

Posted

技术标签:

【中文标题】MouseProc (WH_MOUSE) 事件触发两次【英文标题】:MouseProc (WH_MOUSE) events firing twice 【发布时间】:2017-04-03 19:16:45 【问题描述】:

我想就我遇到的问题提出一个问题。

我使用以下函数安装了一个 WH_MOUSE 钩子:

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

threadId 是使用GetWindowThreadProcessId 函数获取的。这是成功的,因为钩子只在我想要的过程中起作用。 dllInstance 是从 DllMain 入口点获得的。值得一提的是,hMouseHook 位于共享数据段 (#pragma data_seg(".shared"))。以下代码显示了上述 SetWindowsHookEx 调用中提供的 MouseHookProc

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(我仔细检查了)。我的问题是“鼠标按钮按下!”每次按住鼠标左键时会打印两次消息。鉴于提供的代码,为什么会发生这种情况?我目前正在使用一种解决方法,但想了解为什么会发生这种情况。

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

提前感谢您的任何回复。

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

【问题讨论】:

我的期望是HC_NOREMOVE 调用(PeekMessage 调用PM_NOREMOVE)是第一个。我不知道为什么这是第二个电话。您可能可以忽略任何带有HC_NOREMOVE 标志的调用。 完全正常documented behavior. @1201ProgramAlarm 实际上,我只是可耻地假设它是第二个,没有检查。你是对的,HC_NOREMOVE 是第一个。现在我的问题仍然存在,为什么我的程序会被一条 HC_NOREMOVE 消息调用?这段代码的目的是什么? @Hans Passant 我知道这些代码已记录在案,但我在哪里可以找到有关 HC_NOREMOVE 消息代码用途的信息? 【参考方案1】:

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

【讨论】:

以上是关于MouseProc (WH_MOUSE) 事件触发两次的主要内容,如果未能解决你的问题,请参考以下文章

SetWindowsHookEx WH_MOUSE 在 Win7 中的断点处冻结

WH_MOUSE_LL 钩子,避免得到无用的 WM_MOUSEMOVE 事件

C# 中所有触发事件的说明

事件触发机制

js 鼠标移入触发事件。多次触发。

在WPF 中Dowork事件触发不了