getKeyboardState一个密钥延迟
GetKeyboardState one key delay
我正在从事ToUnicodeEx
功能,并且需要键盘状态为输入参数。因此,我使用GetKeyboardState
函数来做到这一点。但是我注意到当我使用修饰符键键入 shift> shift a 时,有一个字符延迟。这是一个例子。
aaa(holding shift 现在)aaaaaaaa(版本 shift> shift )aaaa
当我调试此问题时,我注意到GetKeyboardState
造成了此延迟。我如何处理或防止此延迟?
这是我的整个键盘挂钩Proc。
void proc(KBDLLHOOKSTRUCT kbdStruct) {
fdebug = fopen("debug.txt", "a");
foutput= fopen("output.txt", "a");
WCHAR pwszBuff[9];
WCHAR key[9];
char str[8];
BOOL isDead = FALSE;
BYTE lpKeyState[256];
HWND currentHwnd = GetForegroundWindow();
LPDWORD currentProcessID = 0;
DWORD currentWindowThreadID = GetWindowThreadProcessId(currentHwnd, currentProcessID);
DWORD thisProgramThreadId = GetCurrentThreadId();
hkl = GetKeyboardLayout(thisProgramThreadId);
if (AttachThreadInput(thisProgramThreadId, currentWindowThreadID, TRUE))
{
GetKeyboardState(lpKeyState);
AttachThreadInput(thisProgramThreadId, currentWindowThreadID, FALSE);
}
else
{
GetKeyboardState(lpKeyState);
}
int ret = ToUnicodeEx(kbdStruct.vkCode, kbdStruct.scanCode, lpKeyState, pwszBuff, 8, 0, hkl);
fprintf(fdebug, "vkCode: %dn", (int)kbdStruct.vkCode);
fprintf(fdebug, "ret: %dn", (int)ret);
fprintf(fdebug, "lastIsDead: %dn", (int)lastIsDead);
fprintf(fdebug, "lastIsMod: %dn", (int)lastIsMod);
fprintf(fdebug, "lastVKCode: %dn", (int)lastVKCode);
if (ret == -1) {
isDead = TRUE;
ClearKeyboardBuffer(kbdStruct.vkCode, kbdStruct.scanCode, hkl);
}
else if (ret == 0) {
}
else {
memcpy(&key, &pwszBuff, sizeof(pwszBuff));
WideCharToMultiByte(CP_UTF8, 0, key, -1, str, sizeof(str), NULL, NULL);
fprintf(fdebug, "str: %sn", str);
}
if (lastVKCode != 0 && lastIsDead == TRUE) {
ToUnicodeEx(lastVKCode, lastScanCode, lastKeyState, pwszBuff, 4, 0, hkl);
memcpy(&key, &pwszBuff, sizeof(pwszBuff));
WideCharToMultiByte(CP_UTF8, 0, key, -1, str, sizeof(str), NULL, NULL);
fprintf(fdebug, "str: %sn", str);
lastVKCode = 0;
}
fprintf(fdebug, "%s", "---------------------------------------------------n");
fprintf(foutput, "LSHIFT: %dn", (int)lpKeyState[160]);
fprintf(foutput, "RSHIFT: %dn", (int)lpKeyState[161]);
fprintf(foutput, "%s", "---------------------------------------------------nn");
lastVKCode = kbdStruct.vkCode;
lastScanCode = kbdStruct.scanCode;
lastIsDead = isDead;
fclose(fdebug);
fclose(foutput);
}
这是hookcallback
的更新版本,谢谢Ton Plooij。但是,我仍然有同样的问题。
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT ret = CallNextHookEx(_hook, nCode, wParam, lParam);
if (nCode >= 0)
{
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
hookStruct = *((KBDLLHOOKSTRUCT*)lParam);
proc(hookStruct);
}
}
return ret;
}
AttachThreadInput(thisProgramThreadId, currentWindowThreadID, FALSE);
这并不能做您希望做的事情。有时。当您致电GetKeyboardState()时,这是一项英勇而必要的努力。花了我一段时间来找到故障模式,这一点并不明显,我无法以相同的方式使代码失败。当GUI过程处于前景时,它可以正常工作,例如,使用记事本或VS。
但是不是当它是控制台模式过程时。
解释有点令人费解的是,实际上是返回误导信息的getWindowThreadProcessid()。它试图保持幻想,即拥有控制台窗口的控制台过程。它不是,实际上是拥有它的关联的conhost.exe过程。Windows 7中添加了conhost.exe在旧的Windows版本上的CSRSS.exe,以求解由UIPI引起的拖放 下降问题。
但没有任何不错的方法来发现拥有该窗口的特定conhost.exe过程,更不用说线程ID了。此Q a的主题。非常怀疑它将为您提供帮助。
只有体面的建议是众所周知的令人不愉快的建议:如果您需要可靠地翻译击键,那么您需要使用wh_keyboard挂钩而不是wh_keyboard_ll。因此,getKeyboardState()始终是准确的,挂钩回调在进程中运行。
lowlevelkeyboardproc在其WPARAM中接收WM_KEYUP和WM_KEYDOWN消息。在这种情况下,您可以自己跟踪按压修饰符键,以检测到向下移动。将密钥状态信息存储在静态变量中,并使用它在处理其他键而不是使用getKeyState时测试是否按下移位。
您可以尝试getAsyncKeystate()。我的键盘钩模块中的此功能完美地工作。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v = vs.85).aspx
在按键时,似乎可以捕获硬件中断。
,您的GetKeyboardState与Windows注册表有关。它似乎与Belows有关:
" hkey_users default controlpanel 键盘",修改"键盘delay"值为0 default 1)并将"键盘匹配"值更改为48(Dafault 31)。
根据Hans Passant的答案,我搜索了我如何从GetWindowThreadProcessId()
获得正确的值并成功地获得了hWnd
和windowThreadID
,我每次都在Hook回调中获得这些值,我将这些值仅获得全局变量程序启动和使用的变量后,在钩回调中。
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 允许从 std::map 的密钥窃取资源?
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 在没有密钥的情况下读取密文的剩余噪声预算
- 如何修复无效的API密钥,IP或操作权限错误?
- 所有可能的链接生成器与64位密钥
- 如何在unordered_map中更改密钥?
- 获取当前密钥状态?
- curl_easy_perform() 失败:SSL 对等证书或 SSH 远程密钥不正常
- 将密钥发送到非前台的游戏窗口
- 有哪些方法可以对基于 256 位密钥的矩阵进行加扰?
- 即使另一个应用具有焦点,检测F1密钥的按键(和覆盖)键
- Rapidjson将密钥值从一个文档对象分配到另一个文档对象
- 如何在STD :: MAP中找到具有至少一个数据成员等于密钥的结构的元素
- getKeyboardState一个密钥延迟
- 检查最后一个项目是否通过地图密钥存在
- 好的哈希函数,2个整数用于一个特殊的密钥
- 如何禁用另一个程序中的密钥
- 对于给定的密钥,什么样的随机数生成系统会只返回一个结果
- 在一对多映射中搜索一个密钥