由于Windows注入到所有正在运行的进程的回调函数,将永远是这个代码的多个实例加载。然而,他们都需要分享至少有一个资料片,即需要接收钩子事件通知窗口的句柄。几个令人沮丧的时间阅读共享内存后,我决定,我希望有一个简单的解决方案。这是MSDN文档丢给我一根救命稻草,在形式GetProp和SetProp。
GetProp和SetProp,让您联想到任何类型处理任何窗口的API函数。也就是说,如果你有一个窗口句柄(hWnd),你可以与它相关联的其他任何处理,以这样一种方式,任何应用都可以访问该数据。幸运的是,有一个窗口句柄的本质,在任何Windows会话,桌面处理不断。因此,为了存储窗口接收挂钩事件的处理,我使用桌面窗口的属性。这是一个黑客,但工作非常可靠和有效。 InitializeAbcHook功能检查,看看是否有已命名WILSON_HOOK_HWND_ABC已经与桌面窗口的句柄。假设不存在,这个句柄设置为窗口将接收挂钩事件的处理。
这段代码是在InitializeCbtHook,显示GetProp:
if (GetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_CBT") != NULL) { SendNotifyMessage((HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_CBT"), RegisterWindowMessage("WILSON_HOOK_CBT_REPLACED"), 0, 0); } SetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_CBT", destination);
和SetProp是在CbtHookCallback使用中检索窗口句柄:{C}
这种方法有一个主要问题:它意味着只有一个应用程序可挂接一次这些事件。当第二个应用程序(即使用同一个DLL)开始挂钩事件,第一个应用程序发送一条消息(WILSON_HOOK_CBT_REPLACED),通知它现在它的运气不好,不再挂接任何。因此,如果您使用此代码,在自己的软件,它会是一个好主意,重新编译它,改变WILSON_HOOK字符串不同的东西,使您的应用程序不会发生冲突与任何其他软件,使用这种方法。警告:返回值
我特别的方法来挂钩的其他主要问题是它不会让你一个钩子回调被调用时返回的值。通常情况下,钩子回调函数可以返回一个值,这可能会影响任何事件发生所产生的钩。例如,当提出的CBT CREATEWND钩,设置一个非0的返回值,防止创建窗口。此功能可用于防止创建某些类别或类型的窗口。然而,在其目前的形式,我的解决方案不会允许你设置一个返回值。从理论上说,有一个相当简单的解决方法。我在C DLL使用SendNotifyMessage挂钩的应用程序发送消息,这意味着该DLL刚刚发布一个消息,然后不等待,看看挂钩的应用程序进程。但是,您可以改为使用SendMessage命令,这迫使DLL等待挂钩的应用过程中的钩子和返回Message.Result在托管代码值。这种方法的缺点,而我并没有实现这样的原因,是它可以非常容易导致系统崩溃。如果您的托管代码遇到一个未处理的异常时,执行不会返回到调用SendMessage函数,这反过来又挂起的申请被钩。一个打在短短20分钟左右,很难重新启动SendNotifyMessage的智慧,我相信。RegisterWindowMessage函数
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-29963-2.html
还想看一遍