使用 SetWindowsHookEx 时灵敏度下降
Posted
技术标签:
【中文标题】使用 SetWindowsHookEx 时灵敏度下降【英文标题】:Sensitivity drops when using SetWindowsHookEx 【发布时间】:2021-07-12 14:27:59 【问题描述】:当我将钩子放在鼠标上时,我会周期性地失去灵敏度,它会增加约 0.3 秒(大约两倍)。我怎样才能解决这个问题? 我的处理程序代码:
LRESULT CALLBACK mouseProc(int Code, WPARAM wParam, LPARAM lParam)
MOUSEHOOKSTRUCT* pMouseStruct = (MOUSEHOOKSTRUCT*)lParam;
if (pMouseStruct != nullptr)
switch (wParam)
case WM_LBUTTONDOWN:
std::cout << "WM_LBUTTONDOWN";
break;
case WM_LBUTTONUP:
std::cout << "WM_LBUTTONUP";
break;
case WM_RBUTTONDOWN:
std::cout << "WM_RBUTTONDOWN";
break;
case WM_RBUTTONUP:
std::cout << "WM_RBUTTONUP";
break;
default:
break;
return CallNextHookEx(NULL, Code, wParam, lParam);
我是这样放的:
HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, NULL, 0);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0)
TranslateMessage(&message);
DispatchMessage(&message);
UnhookWindowsHookEx(hook);
【问题讨论】:
两件事 - (1) "...如果 nCode 小于零,则挂钩过程必须将消息传递给 CallNextHookEx 函数而不进行进一步处理..." docs.microsoft.com/en-us/previous-versions/windows/desktop/… 和 (2)std::cout <<
可能会同步。
除了理查德所说的,请注意您使用std::cout
。对于像鼠标这样需要非常长的响应时间的东西来说,它非常慢。
附注:WH_MOUSE_LL
使用 MSLLHOOKSTRUCT
,WH_MOUSE
使用 MOUSEHOOKSTRUCT
。它们不是一回事,所以不要把它们混为一谈。
【参考方案1】:
您在这段代码中失去了敏感性,因为std::cout
非常慢。您需要快速响应此挂钩,否则您显然会失去敏感性。
如果您确实需要登录您的钩子,请使用 spdlog 之类的东西并异步记录所有内容。
此外,正如理查德在 cmets 中提到的,您在钩子开始时需要这样的东西:
if (nCode < 0) // do not process message
return CallNextHookEx(hhook, nCode, wParam, lParam);
【讨论】:
OutputDebugString
是异步的,不会引入另一个依赖项。
我可以通过CreateThread运行代码来提高速度吗?这会有帮助吗?
@IInspectable 你确定它是异步的吗?因为我在 msdn 中没有看到任何地方。
@Elberer 你不能为你的钩子使用线程。问题是记录部分。您需要以一种快速异步的方式登录。您可以自己编写此类日志记录,使用类似的 API 或使用其他库。
一旦OutputDebugString
将其有效负载复制到共享缓冲区中,代码将继续执行。它不会等待调试器观察输出。甚至可能没有调试器在监听。当然,在保护共享缓冲区时会涉及到一些同步,尽管你必须特别不幸地遇到这种争用。 Understanding Win32 "OutputDebugString" 有内部细节。以上是关于使用 SetWindowsHookEx 时灵敏度下降的主要内容,如果未能解决你的问题,请参考以下文章
SetWindowsHookEx WH_KEYBOARD_LL 问题锁屏
在我的线程上下文中调用“SetWindowsHookEx”函数
如何使用 SetWindowsHookEx api 锁定 CTRL+ALT+DEL?