MFC+ 多线线程编程,线程中安装钩子,有时失效。

玉生香 2020-05-26 05:07:22

在下文中 CSchedulerThread::Exec() ,当有处理的指令时,安装钩子,当指令执行完成卸载钩子(程序是MFC+多线程)
钩子实现的功能是关闭全局的物理键盘和鼠标。

1.第一次启动时,有指令执行,钩子正常工作。但调试的时候,进入不了KeyboardProc ,MouseProc两个钩子处理函数。
2.后面再有指令的时候,钩子工作不正常。

该怎么处理。到底是什么原因。






/*全局低级钩子 指令运行时,关闭物理键盘和鼠标,不管虚拟键盘和鼠标*/

HHOOK gMouseHook = NULL; //鼠标钩子
HHOOK gKBordHook = NULL; //键盘钩子

#define DW_EXTRA_DIFF_VIRTUAL_AND_REAL 4294967295
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

if (code >= HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_KEYUP)) //有键按下
{
DWORD vk_code = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
KBDLLHOOKSTRUCT* pkbs = (KBDLLHOOKSTRUCT*)lParam;

if (vk_code == 119 || pkbs->dwExtraInfo == DW_EXTRA_DIFF_VIRTUAL_AND_REAL)
{
return CallNextHookEx(gKBordHook, code, wParam, lParam);
}
return TRUE;

}
return CallNextHookEx(gKBordHook, code, wParam, lParam); //将消息还给钩子链,不要影响别人
}



LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam)
{

if (code >= HC_ACTION ) //有键按下
{
BOOL bEvent = FALSE;
MSLLHOOKSTRUCT *pkbhs = (MSLLHOOKSTRUCT *)lParam;
switch (wParam)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN:
case WM_MBUTTONDBLCLK:
case WM_MOUSEMOVE:
bEvent = TRUE;
break;
}

if (bEvent && pkbhs->dwExtraInfo == DW_EXTRA_DIFF_VIRTUAL_AND_REAL)
{
return CallNextHookEx(gMouseHook, code, wParam, lParam);
}
return TRUE;

}
return CallNextHookEx(gMouseHook, code, wParam, lParam); //将消息还给钩子链,不要影响别人
}



void InstallHook()
{
int codeMouse = 0;
int codeKBord = 0;
if (gMouseHook == NULL)
{
gMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);
codeMouse = GetLastError();
}

if (gKBordHook == NULL)
{
gKBordHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(NULL), 0);
codeMouse = GetLastError();
}

}

void UninstallHook()
{
if (gMouseHook) {
UnhookWindowsHookEx(gMouseHook); // 卸载钩子
gMouseHook = NULL;
}

if (gKBordHook)
{
UnhookWindowsHookEx(gKBordHook); // 卸载钩子
gKBordHook = NULL;
}
}




int CSchedulerThread::Exec() //线程执行函数
{
while (1)
{

DoEveryLoop();
if (GetQuestPack(*m_pQPack))
{
LOG.LOGINF("%s Begin...", m_pQPack->GetSerialNo().c_str());
BOOL bRet = FALSE;
wcomm::charstring sRes;
this->SetTaskSTime();
int s;
if(CIM.SetRunSignal(s))
{
InstallHook(); //安装钩子
bRet = m_pEventEngine->Exec(m_pQPack->GetLuaText());
sRes = m_pEventEngine->getError();
UninstallHook();//卸载钩子
CIM.UnSetRunSignal();

}
else
{
sRes = CIM.GetInterruptDescrible(s);
}
//保存指令最后执行结果 和 坐标
EventTask::Instance()->setResult(bRet);
this->SetResult(bRet, sRes);
this->WriteTask();
InitQuestPack();
PutFileResult(m_pQPack->GetSerialNo(), m_pQPack->GetTaskType(), bRet);
this->SetTaskETime();
this->SetTaskResult(sRes);
this->WriteTaskLog();
LOG.LOGINF("%s End(%s) ...", m_pQPack->GetSerialNo().c_str(), sRes.c_str());
}
else
Sleep(100);
}
return 0;
}


...全文
224 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2020-05-28
  • 打赏
  • 举报
回复
记录 DllMain传入的 HANDLE hinstDLL 句柄 GetModuleHandle(NULL) 用 记录的句柄代替试试看 Hook MSDN 文档中有说明的, 低级键盘和鼠标构造 Global only (DLL)
玉生香 2020-05-28
  • 打赏
  • 举报
回复
引用 3 楼 zgl7903 的回复:
判断钩子是否安装成功, 看错误信息
看Getlasterr()的返回值0
玉生香 2020-05-27
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
可能是 SetWindowsHookEx 传递的 HINSTANCE 参数不对? GetModuleHandle lpModuleName If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file). 试试 DLL 入口处记录 hInst 或者 安装钩子的时候传入DLL入口地址
通过消息的方式传递DIALOG,可以正常使用。直接放在线程里面不能使用。
zgl7903 2020-05-27
  • 打赏
  • 举报
回复
可能是 SetWindowsHookEx 传递的 HINSTANCE 参数不对? GetModuleHandle lpModuleName If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file). 试试 DLL 入口处记录 hInst 或者 安装钩子的时候传入DLL入口地址
zgl7903 2020-05-27
  • 打赏
  • 举报
回复
判断钩子是否安装成功, 看错误信息

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧