У меня есть приложение C ++ (MFC), которому нужно проверять состояние ключа по таймеру. Если пользователь удерживает клавишу, мы задерживаем обработку некоторого кода.
Вот чек на keydown
:
if (!GetKeyboardState(keyState))
{
s_executeDeferredResult = e_executeDeferredButtonCheckFailed;
return;
}
s_executeDeferredStuckKeys.clear();
for (int index=0; index<arrsize(keyState); ++index)
{
if (keyState[index] & 0x80)
{
s_executeDeferredStuckKeys.insert(index);
}
}
if (!s_executeDeferredStuckKeys.empty())
{
s_executeDeferredResult = e_executeDeferredButtonsActive;
return;
}
Но есть некоторые ключевые комбинации, которые застревают:
- Включите NUMLOCK
- Нажмите SHIFT
- Нажмите NumPad8
- Отпустите SHIFT
- Отпустите NumPad8
(это один пример, есть и другие, в том числе дузи с CTRL - ALT - DEL kbd>)
GetKeyboardState
теперь сообщит, что VK_UP
нажата.
Происходящие события (соответствующие действиям выше).
<None>
WM_KEYDOWN
,VK_SHIFT
WM_KEYUP
,VK_SHIFT
WM_KEYDOWN
,VK_UP
WM_KEYDOWN
,VK_SHIFT
WM_KEYUP
,VK_SHIFT
WM_KEYUP
,VK_NUMPAD8
Итак, Windows не распознает, что появилась клавиша «Вверх», и теперь GetKeyboardState
не работает.
Есть ли хороший способ проверить реальное состояние ключа? GetAsyncKeyState
и GetKeyState
оба сообщают, что ключ тоже не работает.
PreTranslateMessage
реализацию. Вот где со временем накапливается всякое плохое. Также обратите внимание на замечание к документацииGetKeyboardState
: < i> Статус меняется, когда поток удаляет сообщения клавиатуры из своей очереди сообщений. Другими словами: если ваше приложение делает что-то подозрительное, есть вероятность, чтоGetKeyboardState
запутается. - person IInspectable   schedule 29.08.2013