it-swarm.com.de

Wie überprüfe ich, ob in C++ eine Taste gedrückt wird?

Wie kann ich überprüfen, ob unter Windows eine Taste gedrückt wird?

6
snivy9014

Wie von anderen erwähnt, gibt es keine plattformübergreifende Methode, aber unter Windows können Sie dies folgendermaßen tun:

Der folgende Code prüft, ob die Taste "A" gedrückt ist.

if(GetKeyState('A') & 0x8000/*Check if high-order bit is set (1 << 15)*/)
{
    // Do stuff
}

Im Falle einer Schicht oder ähnlichem müssen Sie eine der folgenden Optionen bestehen: https://msdn.Microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx

if(GetKeyState(VK_SHIFT) & 0x8000)
{
    // Shift down
}

Das niederwertige Bit zeigt an, ob der Schlüssel umgeschaltet ist.

SHORT keyState = GetKeyState(VK_CAPITAL/*(caps lock)*/);
bool isToggled = keyState & 1;
bool isDown = keyState & 0x8000;

Oh und auch nicht vergessen

#include <Windows.h>
11
Frank S.

Es gibt keine tragbare Funktion, mit der überprüft werden kann, ob eine Taste gedrückt wird, und wenn nicht, wird fortgefahren. Dies ist immer systemabhängig. 

Lösung für Linux und andere Posix-kompatible Systeme:

Hier, für den Code von Morgan Mattews bieten Sie kbhit()-Funktionalität in einer Weise, die mit jedem POSIX-kompatiblen System kompatibel ist. Er nutzt den Trick, die Pufferung auf Termi-Ebene zu deaktivieren.

Lösung für Windows:

Für Windows bietet Microsoft _kbhit()

2
Christophe

prüfen Sie, ob eine Taste gedrückt wird, wenn ja, dann erledigen Sie den Vorgang

Betrachten Sie 'select ()', wenn diese (angeblich Posix) Funktion auf Ihrem Betriebssystem verfügbar ist.

'select ()' verwendet 3 Bitsätze, die Sie mit den bereitgestellten Funktionen erstellen (siehe man select, FD_SET usw.). Sie müssen wahrscheinlich nur die Eingabebits erstellen (vorerst)


von der Manpage:

'select ()' "ermöglicht einem Programm die Überwachung mehrerer Dateideskriptoren und wartet, bis einer oder mehrere der Dateideskriptoren für eine Klasse von E/A-Operationen" bereit "werden (z. B. Eingabe möglich). Ein Dateideskriptor wird als" ready "betrachtet Es ist möglich, eine entsprechende E/A-Operation auszuführen (z. B. Lesen (2), ohne zu blockieren ...) "

Wenn select aufgerufen wird:

a) die Funktion betrachtet jede in den Sets identifizierte FD, und wenn dieser Fd-Status angibt, dass Sie etwas tun können (möglicherweise lesen, möglicherweise schreiben), wird select zurückkehren und das tun, was Sie tun müssen ... 'alles, was Sie tun müssen' scannt die Bits, sucht das gesetzte Bit und reagiert auf die mit diesem Bit verknüpfte fd. 

Der 1. Satz (in select übergeben) enthält aktive Eingangs-Fds (normalerweise Geräte). Wahrscheinlich ist 1 Bit in diesem Set alles, was Sie brauchen. Und mit nur 1 fd (d. H. Einer Eingabe über die Tastatur) und 1 Bit ist dies alles ziemlich einfach. Mit dieser Rückkehr von select können Sie "Sachen erledigen" (vielleicht nachdem Sie das Zeichen abgerufen haben).

b) Die Funktion hat auch ein Timeout, mit dem Sie festlegen, wie viel Zeit auf eine Änderung des Status fd warten soll. Wenn sich der fd-Status nicht ändert, führt das Zeitlimit dazu, dass 'select ()' mit einer 0 zurückkehrt. (D. H. Keine Tastatureingabe). Ihr Code kann zu diesem Zeitpunkt ebenfalls etwas tun, möglicherweise eine Ausgabe.

fyi - fd sind normalerweise 0,1,2 ... Denken Sie daran, dass C 0 als STDIN, 1 und STDOUT verwendet.


Einfache Testeinrichtung: Ich öffne ein Terminal (getrennt von meiner Konsole) und gebe den Befehl tty in dieses Terminal ein, um seine ID zu finden. Die Antwort lautet in der Regel etwas wie "/ dev/pts/0" oder 3 oder 17 ... 

Dann bekomme ich eine Fd, die ich in 'select ()' verwenden kann:

// flag options are: O_RDONLY, O_WRONLY, or O_RDWR
int inFD = open( "/dev/pts/5", O_RDONLY ); 

Es ist nützlich, diesen Wert zu ermitteln. 

Hier ist ein Ausschnitt (von Man select) zu beachten:

  fd_set rfds;
  struct timeval tv;
  int retval;

  /* Watch stdin (fd 0) to see when it has input. */
  FD_ZERO(&rfds);
  FD_SET(0, &rfds);

  /* Wait up to five seconds. */
  tv.tv_sec = 5;
  tv.tv_usec = 0;

  retval = select(1, &rfds, NULL, NULL, &tv);
  /* Don't rely on the value of tv now! */

  if (retval == -1)
      perror("select()");
  else if (retval)
      printf("Data is available now.\n");  // i.e. doStuff()
      /* FD_ISSET(0, &rfds) will be true. */
  else
      printf("No data within five seconds.\n"); // i.e. key not pressed
1
2785528