我创建了一个DLL来使用CBT钩子挂钩一些事件。它似乎只适用于启动钩子的过程创建的窗口......
我的系统是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;
}
任何提示?
答案 0 :(得分:3)
当Windows安装globals钩子时,实现钩子函数的DLL通常会加载到其他进程中。在这些进程中,g_hNotifyWin
和g_uNotifyMsg
全局变量为NULL。在发生SetCbtHook
调用的过程中,全局变量不是NULL。
您必须有办法在任意过程中检索g_hNotifyWin
和'g_uNotifyMsg'的正确值。
添加:
const char * g_pszClassName = "MyClassName";
const char * g_pszRegisteredMsg = "MyMessage";
到你的DLL,并用g_hNotifyWin
窗口的类名替换“MyClassName”。查看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。
答案 1 :(得分:1)
我猜你的ThreadId不是零,所以hook只分别附加到调用进程/线程。阅读文档: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx