TL; DR: è possibile utilizzare GetAsyncKeyState per verificare se una chiave è attualmente verso il basso, ma per la migliore risposta delle applicazioni alla pressione dei tasti e rilascia, si desidera utilizzare il codice di condotta Win32 vicino al fondo del mio post.
GetAsyncKeyState opere perfettamente bene per determinare se una chiave è attualmente verso il basso, ma in termini di determinare se un tasto è stato premuto o rilasciato e quante volte questo è stato fatto, GetAsyncKeyState perde delle battute in una CPU- applicazione intensiva, anche dopo aver memorizzato lo stato della chiave precedente.
questo era quello che ho provato:
static const unsigned int NumberOfKeys = 256U;
bool previousKeyboardState[NumberOfKeys];
//Get the current state of each key as the application starts to ensure that keys held down beforehand are not processed as pressed keys.
for (unsigned int keyNum = 0U; keyNum < NumberOfKeys; ++keyNum)
{
previousKeyboardState[keyNum] = isKeyDown(keyNum);
}
//Works fine.
bool isKeyDown(int key)
{
return (GetAsyncKeyState(key) & (1 << 16));
}
//Misses key presses when application is bogged down.
bool isKeyFirstPressed(int key)
{
bool previousState = previousKeyboardState[key];
previousKeyboardState[key] = isKeyDown(key);
return (previousKeyboardState[key] && !previousState);
}
//Misses key releases when application is bogged down.
bool isKeyFirstReleased(int key)
{
bool previousState = previousKeyboardState[key];
previousKeyboardState[key] = isKeyDown(key);
return (!previousKeyboardState[key] && previousState);
}
//Example usage:
if (isKeyDown(VK_W))
{
//W key.
}
if (isKeyFirstReleased(VK_SNAPSHOT))
{
//Print screen.
}
GetKeyboardState è non va bene neanche, in quanto non tiene traccia del numero di tasti da premere o rilasci. Come ha detto Erik Philips nella sua risposta, queste sono soluzioni senza buffer, che non vanno bene se si è, ad es. scrivere un gioco. Dovresti elaborare tutte le sequenze di tasti più velocemente di quanto non siano state ricevute.
Ora, il mio codice sopra funziona in modo decente e può essere adatto a molte persone, ma preferisco di gran lunga non perdere un singolo tasto. I odio utilizzando applicazioni che non rispondono. Penso che la soluzione migliore per le applicazioni Win32 sia quella di catturare i messaggi WM_KEYDOWN e WM_KEYUP nella pipeline ed elaborarli. La cosa bella è che WM_KEYDOWN fornisce anche un conteggio a ripetizione automatica, che potrebbe essere utile per le applicazioni che supportano l'immissione di testo (ad es. Chat, IDE, ecc.). Questo aggiunge anche una piccola complicazione, che è menzionato nella documentazione WM_KEYDOWN:
A causa della caratteristica Autorepeat, più di un messaggio WM_KEYDOWN può essere pubblicato prima che un messaggio WM_KEYUP è distaccato. Lo stato del tasto precedente (bit 30) può essere utilizzato per determinare se il messaggio WM_KEYDOWN indica la prima transizione verso il basso o una transizione verso il basso ripetuta.
Ci sono anche ganci per tastiera di Windows che è possibile esaminare, ma sono più difficili da usare. Sono bravi a ricevere key press globali.
"Sembra che la messaggistica delle finestre sia lenta." Veramente? Questo è difficile da determinare poiché è impossibile per il programma calcolare il ritardo tra il momento in cui l'utente ha premuto il tasto e il momento in cui è stato elaborato il messaggio della finestra. È per sentito dire che in qualche modo l'hai misurato per essere troppo lento? –
L'ho misurato in loop in tempo reale, in genere occorrono alcune zecche per dare il via. E l'ho anche sentito molte volte negli ultimi anni. – judeclarke
@judeclarke: Quanto dura un "tick"? E come definisci "lento"? –