我创建了一个 DLL 来使用 CBT Hook 来 Hook 一些事件。它似乎只适用于由启动 Hook 的进程创建的窗口...
我的系统是 Windows 7 x64,但 x32 上的行为也是相同的。
这是代码(抱歉,我不是 C++ 专家):
#include "windows.h"
extern "C"
{
static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam);
HINSTANCE g_hDll = NULL;
HWND g_hNotifyWin = NULL;
DWORD g_uNotifyMsg = NULL;
HHOOK g_hHook = NULL;
__declspec(dllexport) HHOOK SetCbtHook(HWND hWnd, LPCWSTR lStrMsg, DWORD threadId)
{
g_hNotifyWin = hWnd;
g_uNotifyMsg = RegisterWindowMessage(lStrMsg);
g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CbtProcCb, g_hDll, threadId);
return g_hHook;
}
__declspec(dllexport) int UnsetCbtHook()
{
if ( !g_hHook )
return 0;
return UnhookWindowsHookEx(g_hHook);
}
}
static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam)
{
SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if ( fdwReason == DLL_PROCESS_ATTACH )
g_hDll = hinstDLL;
return true;
}
有什么提示吗?
最佳答案
当Windows安装全局钩子(Hook)时,实现钩子(Hook)函数的DLL往往会被其他进程加载。在这些进程中,g_hNotifyWin
和 g_uNotifyMsg
全局变量为 NULL。该全局变量仅在发生 SetCbtHook
调用的进程上下文中不为 NULL。
您必须有办法在任意进程中检索 g_hNotifyWin
和“g_uNotifyMsg”的正确值。
添加:
const char * g_pszClassName = "MyClassName";
const char * g_pszRegisteredMsg = "MyMessage";
到您的 DLL,并将“MyClassName”替换为 g_hNotifyWin
窗口的类名。请参阅 EXE 中的 RegisterClass
调用。还更新“MyMessage”。
然后,使用以下CbtProcCb
函数:
static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam)
{
if ( nCode >= 0 ) {
if ( g_hNotifyWin == NULL ) g_hNotifyWin = FindWindow( g_pszClassName, NULL );
if ( g_uNotifyMsg == 0) g_uNotifyMsg = RegisterWindowMessage(g_pszRegisteredMsg);
if ( g_hNotifyWin && g_uNotifyMsg )
SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event
}
return CallNextHookEx(NULL, nCode, wParam, lParam); // first arg useless see MSDN
}
编辑:
正如您在评论中指出的,g_uNotifyMsg
也存在同样的问题,请参阅更新的函数。事实上,您可以在 DllMain
中设置这些变量。
CallNextHookEx 的第一个参数可能为 NULL。
关于c++ - CBT Hook 仅接收一些事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359189/