我想自己绘制和移动我的窗口(使用chromium嵌入式框架)。要做到这一点,当鼠标在我的窗口外移动时,我需要一个全局回调——所以我安装了一个低级别的鼠标挂钩:
hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, hInstance, NULL);
钩子简单地抓取鼠标事件并调用"CallNextHookEx"。这里没有问题,一切都很顺利。我现在的问题是:如果调试器坏了或者抛出了异常,我就不能再移动鼠标了。。
我试着在另一个线程中处理钩子,就像这样:
HANDLE mouseProcHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mouseProcessor, NULL, NULL, &dwMouseProcThread);
DWORD WINAPI Win32Application::mouseProcessor(LPVOID lpParm) {
hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, ((Win32Application*)Application::getInstance())->hInstance, NULL);
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(hMouseLLHook);
return 0;
}
但这也不能解决问题。有没有变通方法、解决方案或其他方法可以做到这一点?此外,我认为低级别的钩子可能没有必要,因为我只需要被告知移动,如果我是最后一个排队的人,那也不会有问题,所以系统/其他进程可以首先处理鼠标回调。
为了进一步阐明这一点:当您拦截所有鼠标移动事件时,它们都会出现在您的钩子中,钩子可以修改或吞噬它们。因此,系统会调用钩子中的每个鼠标移动事件,并等待钩子例程完成,直到它再次为下一个挂起的鼠标移动事件调用钩子。
猜猜当你在钩子事件中闯入调试器时会发生什么?在完成挂钩程序之前,不再发生鼠标事件。通常情况下,你可以用这样一个中心钩来摧毁你的整个系统。但幸运的是,Windows确实预料到了糟糕的挂钩。您会注意到,在一段时间后,系统会再次响应鼠标事件。我的猜测是,当Windows挂起一次时,它会简单地删除你的钩子。
现在关于调试:安全进入调试器的唯一方法是在挂钩后永远不要触摸鼠标。不太实用。唯一的方法是跟踪有趣的事情,并查看日志文件中钩子内部发生了什么。如果你正在研究如何勾选鼠标和键盘事件的示例代码,你可以看看这里:
http://etwcontroler.codeplex.com/SourceControl/latest#ETWControler/Hooking/Hooker.cs
当调试器停止整个程序(它的所有线程)时
如果使用钩子,可能没有解决方法
不那么准确,但您可以在线程中轮询GetCursorPos。