裸分求:关于dll中钩子键盘本程序的问题!! 本帖最后由 kongling12 于 2010-09-10 23:47:47 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId()); 您好,仍然没有用....贴上测试代码LRESULT CALLBACK KeyProc(int nCode, WPARAM wParam, LPARAM lParam){ MessageBoxA(NULL, "1","1", MB_OK); return ::CallNextHookEx(hOk, nCode, wParam, lParam);}void CAsaApp::InstallHook(){ hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId()); if (hOk == NULL) //因为没有传进参数 这能这样得到进程的线程,但是失败,如果吧最后的参数改成0,则hook失败 { MessageBoxA(NULL, "hook is false", "!!", MB_OK); return; } else { MessageBoxA(NULL, "hook is success", "!!", MB_OK); return; }} hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId());这样安装的话,钩子究竟是安装不成功还是没有效果?如果是没有效果的话,那说明那个软件的界面部分与加载你的DLL的那段代码不在同一个线程,因此GetCurrentThreadId没有获得界面线程的ID。如果你能获得那个软件的窗口句柄(你打算在哪个窗口里响应Ctrl+F5,你就用哪个窗口的句柄),那么你可以通过GetWindowThreadProcessId来获取它的线程ID。 GetCurrentThreadId()得到的是当前的线程ID,这个和你要钩的线程是不是一个线程啊? void CAsaApp::InstallHook(){ HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本"); if (hnotpd == NULL) { MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK); return; } DWORD dwId; GetWindowThreadProcessId(hnotpd, &dwId); if (dwId == NULL) { MessageBoxA(NULL, "dwId is null", "!!", MB_OK); return; } hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwId); if (hOk == NULL) //这里总是提示hOk=NULL { MessageBoxA(NULL, "hook is false", "!!", MB_OK); return; } else { MessageBoxA(NULL, "hook is success", "!!", MB_OK); return; }} 现在改成这样可以hook成功但是 没有效果void CAsaApp::InstallHook(){ HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本"); if (hnotpd == NULL) { MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK); return; } DWORD dwId,dwThreadId; dwThreadId = GetWindowThreadProcessId(hnotpd, &dwId); if (dwId == NULL) { MessageBoxA(NULL, "dwId is null", "!!", MB_OK); return; } hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwThreadId); if (hOk == NULL) { MessageBoxA(NULL, "hook is false", "!!", MB_OK); return; } else { MessageBoxA(NULL, "hook is success", "!!", MB_OK); return; }} 把钩子写在当前模块中的方法仅适合于在本进程内部安装钩子。此时SetWindowsHookEx的第三个参数必须是NULL,而第四个参数则是想要安装钩子的线程(必须是本进程内的线程)。如果要钩其它进程(比如记事本)中的消息,你的钩子必须写在一个独立的DLL文件中,并且安装钩子的时候,必须用LoadLibrary所返回的hModule作为SetWindowsHookEx的第三个参数,GetProcAddress所返回的值作为第二个参数,然后第四个参数设为0。例如:HOOKPROC hkprcSysMsg; static HINSTANCE hinstDLL; static HHOOK hhookSysMsg; hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll"); hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0); theApp.m_hInstance传的不对吧,这时你应该传的是DLL模块句柄的,可以用GetModuleHandle获取还有,你是跨进程操作吗,如果跨进程,最好用:hOk = SetWindowsHookEx(WH_KEYBOARD_LL,KeyProc,GetModuleHandle(TEXT("kbFilter")),0);另外,在KeyProc中别忘了用CallNextHookEx回调hOK。一般都是可以的 如果是本进程的话。没有必要使用hook,PreTranslateMsg就可以 vc中GLSL编译错误 win32环境下 怎样才能使用CEdit?? 关于socket中的缓冲区的问题! 在非MFC的VC编程中,如果要取出时间并且格式化怎么办? 有没有擅长写注册表的高手? 一简单问题 如何加密文件夹? VC中用Sleep函数能实现待时,如何在待时时能进行其它操作(不用多线程) 数字图像处理的小问题 有状态MTS组件何时该调用setcomplete? 求casyncsocket实现通信的示例代码 一用到 读写数据库部分 任务管理器里的内存显示就开始慢慢增加
{
MessageBoxA(NULL, "1","1", MB_OK);
return ::CallNextHookEx(hOk, nCode, wParam, lParam);
}
void CAsaApp::InstallHook()
{
hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId());
if (hOk == NULL) //因为没有传进参数 这能这样得到进程的线程,但是失败,如果吧最后的参数改成0,则hook失败
{
MessageBoxA(NULL, "hook is false", "!!", MB_OK);
return;
}
else
{
MessageBoxA(NULL, "hook is success", "!!", MB_OK);
return;
}
}
这样安装的话,钩子究竟是安装不成功还是没有效果?如果是没有效果的话,那说明那个软件的界面部分与加载你的DLL的那段代码不在同一个线程,因此GetCurrentThreadId没有获得界面线程的ID。
如果你能获得那个软件的窗口句柄(你打算在哪个窗口里响应Ctrl+F5,你就用哪个窗口的句柄),那么你可以通过GetWindowThreadProcessId来获取它的线程ID。
void CAsaApp::InstallHook()
{
HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本");
if (hnotpd == NULL)
{
MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK);
return;
}
DWORD dwId;
GetWindowThreadProcessId(hnotpd, &dwId);
if (dwId == NULL)
{
MessageBoxA(NULL, "dwId is null", "!!", MB_OK);
return;
}
hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwId);
if (hOk == NULL) //这里总是提示hOk=NULL
{
MessageBoxA(NULL, "hook is false", "!!", MB_OK);
return;
}
else
{
MessageBoxA(NULL, "hook is success", "!!", MB_OK);
return;
}
}
现在改成这样可以hook成功但是 没有效果void CAsaApp::InstallHook()
{
HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本");
if (hnotpd == NULL)
{
MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK);
return;
}
DWORD dwId,dwThreadId;
dwThreadId = GetWindowThreadProcessId(hnotpd, &dwId);
if (dwId == NULL)
{
MessageBoxA(NULL, "dwId is null", "!!", MB_OK);
return;
}
hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwThreadId);
if (hOk == NULL)
{
MessageBoxA(NULL, "hook is false", "!!", MB_OK);
return;
}
else
{
MessageBoxA(NULL, "hook is success", "!!", MB_OK);
return;
}
}
如果要钩其它进程(比如记事本)中的消息,你的钩子必须写在一个独立的DLL文件中,并且安装钩子的时候,必须用LoadLibrary所返回的hModule作为SetWindowsHookEx的第三个参数,GetProcAddress所返回的值作为第二个参数,然后第四个参数设为0。例如:
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0);
theApp.m_hInstance传的不对吧,这时你应该传的是DLL模块句柄的,可以用GetModuleHandle获取还有,你是跨进程操作吗,如果跨进程,最好用:
hOk = SetWindowsHookEx(WH_KEYBOARD_LL,KeyProc,GetModuleHandle(TEXT("kbFilter")),0);另外,在KeyProc中别忘了用CallNextHookEx回调hOK。
一般都是可以的