Имам приложение на 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
(това е един пример, има и други, включително doozy с 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 не разпознава, че се е появил клавишът Up и сега GetKeyboardState
е повреден.
Има ли някакъв добър начин да се провери реалното състояние на ключа? GetAsyncKeyState
и GetKeyState
съобщават, че ключът също е свален.
PreTranslateMessage
. Там с времето се натрупват всякакви лоши неща. Обърнете внимание и на забележката в документациятаGetKeyboardState
: < i>Състоянието се променя, тъй като нишката премахва съобщенията от клавиатурата от своята опашка със съобщения. С други думи: Ако приложението ви направи нещо подозрително, има вероятностGetKeyboardState
да се обърка. - person IInspectable   schedule 29.08.2013