WH_KEYBOARD_LL的问题

allenhiman 2014-03-18 10:28:17
程序是一个虚拟桌面的程序 需要监测win+E的组合按键,因为同时不能让windows操作系统真实桌面捕捉这个组合键消息,用到了
SetWindowsHookEx( WH_KEYBOARD_LL, KeyboardProc, theApp.m_hInstance, 0 );
一般情况下 一切正常, 可是测试人员经过不懈的努力 发现有时候会出现win+E失效的问题 我在KeyboardProc里 打调试信息 发现失效的情况下 调试信息无法输出了 看起来就像是这个hook完全失效了。 查阅了一些资料 看到了这样一段话 貌似和我相关 但没说解决方案
WH_KEYBOARD_LL 低级键盘hook,这种方式,优先应用程序处理后再交给系统。
但是容易引起 “无限循环或者挂起”


现在就是想问问 有人遇到同类问题吗 那个“无限循环或者挂起”在什么样的情况下 才会引发呢 可以举个例子吗?
...全文
476 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
allenhiman 2014-04-21
  • 打赏
  • 举报
回复
多谢提醒 这个问题始终也没有解决 其实 对于我们的情况 驱动反而不好用 原因很多 所以目前无解 随便结贴吧
向立天 2014-04-21
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
q_qqq_qqqq 2014-03-20
  • 打赏
  • 举报
回复
我也遇到了类似的情况,求答案,帮顶。。。
allenhiman 2014-03-18
  • 打赏
  • 举报
回复
hook函数体内没有什么特殊和复杂的操作 就是发现嗯了某些组合键盘后给窗口post消息 特殊的就是 发现嗯的是win键就直接返回了
if ( (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) )
{
return TRUE;
}
allenhiman 2014-03-18
  • 打赏
  • 举报
回复
LRESULT CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
KBDLLHOOKSTRUCT *Key_Info = (KBDLLHOOKSTRUCT*)lParam;
if (HC_ACTION == nCode)
{
OutputDebugStringA("Ok hook code xxxxxxxxxxxxxxxxx");
if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN == wParam)
{
OutputDebugStringA("Detect key down!!!!!!!!!!!!!!!!!");
if (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN)
{
if( !g_isWinkeyPressed )
{
isOnlyWinkeyPressed = TRUE;
SetKeyState( Key_Info->vkCode, 1 );
g_isWinkeyPressed = TRUE;
}
}
else
{
isOnlyWinkeyPressed = FALSE;
if (Key_Info->vkCode == L'R' )
{
if( IsWinkeyPressed() && !IsKeyPressed(L'R') )
{
SetKeyState( Key_Info->vkCode, 1 );
::PostMessage( g_hwndThis, MSG_WIN_SHORTCUT, L'R', 0 );
return TRUE;
}
}
else if (Key_Info->vkCode == L'E' )
{
if( IsWinkeyPressed() && !IsKeyPressed(L'E') )
{
SetKeyState( Key_Info->vkCode, 1 );
::PostMessage( g_hwndThis, MSG_WIN_SHORTCUT, L'E', 0 );
return TRUE;
}
}
}
if ( (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) )
{
return TRUE;
}
}
// Win key short cut
if (WM_KEYUP == wParam || WM_SYSKEYUP == wParam)
{
SetKeyState( Key_Info->vkCode, 0 );
if ( (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) )
{
g_isWinkeyPressed = FALSE;
if( isOnlyWinkeyPressed )
{
::PostMessage( g_hwndThis, MSG_BN_LBUTTONDOWN, TRUE, 0 );
}
}
else if (Key_Info->vkCode == VK_OEM_3 && IsCtrlPressed() )
{
::PostMessage( g_hwndThis, MSG_SWITCH_KEYUP, TRUE, 0 );
if (Key_Info->dwExtraInfo == 0)
{
::PostMessage( g_hwndThis, MSG_KEYBOARDPRESS, 0, 0);
}
}
else if (Key_Info->vkCode == VK_DELETE && !IsCtrlPressed() && !IsAtlPressed())
{
if (theApp.m_pMainDlg->m_hWnd == GetActiveWindow())
{
::PostMessage( g_hwndThis, MSG_DELETE_FILE, TRUE, 0 );
}

if (Key_Info->dwExtraInfo == 0)
{
::PostMessage( g_hwndThis, MSG_KEYBOARDPRESS, 0, 0);
}
}
else if (Key_Info->vkCode == L'L' && IsWinkeyPressed() )
{
VKLockScreen();
if (Key_Info->dwExtraInfo == 0)
{
::PostMessage( g_hwndThis, MSG_KEYBOARDPRESS, 0, 0);
}
}
else
{
if (Key_Info->dwExtraInfo == 0)
{
::PostMessage( g_hwndThis, MSG_KEYBOARDPRESS, 0, 0);
}
}
if ( (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) )
{
return TRUE;
}
}
}
return(CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam));
}
allenhiman 2014-03-18
  • 打赏
  • 举报
回复
感谢大家的回复
引用 3 楼 fdsdfdsf 的回复:
建议使用驱动搞定,没有乱七八糟的问题
这个提议可以考虑
引用 4 楼 xuddk727 的回复:
没有正确返回就会挂起。至于重入问题没遇到过,猜想可根据时间戳滤掉
由于explorer。exe已经注册了"win+e"这个快捷键 我之所以利用钩子 就是为了不让exploer.exe接收到这个消息 所以发现嗯了win键后 并没有返货callnext..而是直接 return true 不然exploer。exe也会接收到这个消息.
许文君 2014-03-18
  • 打赏
  • 举报
回复
没有正确返回就会挂起。至于重入问题没遇到过,猜想可根据时间戳滤掉
fdsdfdsf 2014-03-18
  • 打赏
  • 举报
回复
建议使用驱动搞定,没有乱七八糟的问题
fdsdfdsf 2014-03-18
  • 打赏
  • 举报
回复
低级键盘钩子和调用链有关,最后挂上的钩子函数优先级高,不排除系统文件会挂这个钩子
赵4老师 2014-03-18
  • 打赏
  • 举报
回复
至少需要避免你的代码重入吧,我想。

15,979

社区成员

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

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