【发布时间】:2010-11-30 17:01:19
【问题描述】:
我在 WM_MOUSE 上定义了一个全局挂钩,它可以在一段时间内完美运行。每次鼠标移动时,它都会向特定窗口发布一条消息。
随机时间后,钩子停止发送消息。如果我取消注册并注册钩子,它会再次工作。我想在 Windows 中发生的某些特定事情会导致钩子停止,但我找不到什么。
有什么想法吗?
编辑:当钩子不再处于活动状态时,我将调试器附加到其他进程,并且我观察到不再加载 dll。
什么可能导致挂钩 dll 卸载?
Edit2:我发现 MouseHookProc 中的崩溃,任何进程中的 dll 都会从它加载的每个进程中卸载钩子 dll。我无法在我的代码中找到导致崩溃的原因。可能是一些比赛条件或什么?这是钩子dll代码:
#include "stdafx.h"
// define a data segment
#pragma data_seg(".SHARED")
HWND hwnd=0;
HHOOK hHook=0;
#pragma data_seg()
// tell the linker to share the segment
#pragma comment(linker, "/section:.SHARED,RWS")
#define WM_MOUSEHOOK WM_USER+0x100
HINSTANCE hInstance=0;
// this allow to build a very small executable without any extra libraries
// (probably not the problem, the bug still occurs without this )
#ifndef _DEBUG
void *__cdecl operator new(unsigned int bytes)
{
return HeapAlloc(GetProcessHeap(), 0, bytes);
}
void __cdecl operator delete(void *ptr)
{
if(ptr) HeapFree(GetProcessHeap(), 0, ptr);
}
extern "C" int __cdecl __purecall(void)
{
return 0;
}
#endif
BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
hInstance=hModule;
return TRUE;
}
LRESULT CALLBACK MouseHookProc(int nCode, WORD wParam, DWORD lParam)
{
if(nCode==HC_ACTION && (wParam==WM_MOUSEMOVE || wParam==WM_NCMOUSEMOVE))
{
MSLLHOOKSTRUCT *mhs=(MSLLHOOKSTRUCT*)lParam;
PostMessage(hwnd, WM_MOUSEHOOK, wParam, 0);
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}
extern "C" __declspec(dllexport) HHOOK InitializeWindowsHook(char *title)
{
hwnd=FindWindow(0, title);
if(hwnd)
hHook=SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, hInstance, 0);
return hHook;
}
extern "C" __declspec(dllexport) BOOL DeinitializeWindowsHook()
{
if(hHook) {
BOOL b=UnhookWindowsHookEx(hHook);
hHook=0;
return b;
}
return FALSE;
}
【问题讨论】:
-
你是否将消息传播到链中的其他钩子?
-
我注意到虽然你有一个
WH_MOUSE钩子,但你使用MSLLHOOKSTRUCT而不是MOUSEHOOKSTRUCT结构。 -
其实你声明了
*mhs但是你没有使用它。 -
是的,我也试过 LL 钩子。我不想因为害怕删除对错误有意义的东西而过多地编辑代码。当然 mhs 是没用的,但我看不出它是如何导致崩溃或行为不端的。
-
您使用的是 Windows 7 吗?我发现了这个线程:social.msdn.microsoft.com/Forums/en/…,它讨论了一个类似的问题。我自己也有同样的麻烦;如果 CPU 很忙,钩子(显然)超时并且永远不会再次被调用。
标签: c++ windows winapi mouse-hook