在这里的第一篇文章,多年来我一直在思考这个问题的正确解决方案。
我有自己的 UI 引擎和自己的键盘处理,并使用它来显示游戏覆盖。游戏覆盖本身对键盘和窗口事件都是透明的,以便对游戏的干扰最小,但为了使覆盖本身具有交互性,我需要诉诸键盘和鼠标挂钩来阻止某些事件到达游戏。对于鼠标输入,这非常简单,而且效果很好。这是我遇到问题的低级键盘挂钩。
在这一点上,我有一些在大多数情况下都可以使用的东西。我设法解决了几个涉及死键和错误输入的问题,但从未设法创建一个可以主动阻止游戏键盘输入的钩子 - 总是会出错。
例如,当用户试图在覆盖层上的文本框中写入一些文本并且不希望游戏处理相同的击键时,主动阻止键盘输入将是最有用的。
我当前的问题是,如果我通过在挂钩过程中返回非零值来阻止键盘输入,则覆盖的 UI 引擎将停止感知Ctrl键的状态,从而导致无法复制/粘贴到覆盖的文本框中。有趣的是,在Alt-Tab'ing之前,一切正常,但在那之后,Ctrl钩子抓住的按键从VK_CONTROL变为VK_LCONTROL。更有趣的是,无论GetKeyState(VK_CONTROL)是GetAsyncKeyState(VK_CONTROL)还是GetAsyncKeyState(VK_LCONTROL)在 UI 端都没有将Ctrl键注册为按下状态。
由于多年的实验和变通方法,下面的键盘钩子代码有点乱。我会尽可能评论它。
LRESULT __stdcall KeyboardHook( int code, WPARAM wParam, LPARAM lParam )
{
// this is an early exit if the game tells me that it actively has focus
if ( disableHooks || mumbleLink.textBoxHasFocus )
return CallNextHookEx( 0, code, wParam, lParam );
// the following two early exits are remnants …Run Code Online (Sandbox Code Playgroud)