Hi Zusammen
Habe ein kleines Problem bzgl. getch() nach GetAsyncKeyState().
Gleich mal mein Codeausschnitt:
1
intretKey;
2
while((GetAsyncKeyState(VK_ESCAPE))||(GetAsyncKeyState(VK_RETURN))||(GetAsyncKeyState(VK_LEFT))||(GetAsyncKeyState(VK_RIGHT)));//warten bis Tasten losgelassen wurden
3
Sleep(20);
4
fflush(stdin);//bringt leider nichts!
5
while(1)//Endlosschleife hier als Beispiel
6
{
7
retKey=_getch();
8
printf("%c",((char)(retKey)));//nur für Testphase
9
}
Eigentlich erwarte ich jetzt, dass ich beliebige Tasten drücken kann und
mir diese anschliessend auf der Konsole ausgegeben werden. Macht es
auch, aber erst nachdem der ganze Input Buffer ausgelesen wurde, in
welchem sich noch alle meine vorangehenden Pfeiltasten, ENTER und co
befinden! Dh meine Konsole wird erstmal zugemüllt mit '\n' und 'Ó'
(Ó->0xE0, siehe: https://msdn.microsoft.com/en-us/library/078sfkak.aspx
unter "Remarks").
Wie kann ich dieses Problem umgehen? fflush(stdin) bringt ja anscheinend
nichts an dieser Stelle...
Die eingegebenen Tasten sollen später NICHT ausgegeben werden. Ich
verwende hier den printf nur um das Problem zu veranschaulichen.
Danke im voraus...
>_getch, _getwch>When reading a function key or an arrow key, each function must be called twice;
the first call returns 0 or 0xE0, and the second call returns the actual key code.
Also (sofern extended keycodes ignoriert werden sollen)
1
_getch-->0oder0xE0?--Nein-->Zeichenausgeben
2
^|
3
|J
4
|a
5
||
6
|V
7
------------_getch()
Das ist in C eine Schleife mit einem if darin.
GetAsyncKeyState() ist eine ganz andere API auf einer ganz anderen Ebene
des Betriebssystems.
Wäre ne ganz einfache Idee, aber kann ich leider nicht nutzen :(
Problem ist, wenn man zuvor versehentlich eine andere Taste (zB einen
Buchstaben) gedrückt hatte. Die Schleife würde alles bis zu diesem
Zeichen perfekt entfernen, dann aber den versehentlichen Wert übernehmen
und wenn jetzt danach noch ein ENTER kommt (und das wird so sein), wird
ein falscher Wert abgespeichert. (mit ENTER oder ESC wird die while(1)
quasi wieder verlassen)
Wäre super einfach deine Schleife, aber ist leider nutzlos für mein
Problem :(
Gibt es keine andere Möglichkeit diesen Input Buffer zu leeren?
Llemaban schrieb:> Wäre ne ganz einfache Idee, aber kann ich leider nicht nutzen :(
Das solltest Du aber, denn sonst druckst du da Steuerzeichen in die
Konsole...
Aber dann zum Problem:
Kann man den Buffer nicht leer lesen oder ggf. das File-Handle neu
öffnen?
Tendenziell würde ich nicht versuchen, APIs zu mischen, die auf
verschiedenen Ebenen liegen, da ist sowas vorprogrammiert, weil die
Interaktion zwischen diesen Ebenen nicht ganz durchsichtig ist.
Vielleicht ist das hier für deine Zwecke besser geeignet:
https://docs.microsoft.com/en-us/windows/console/console-functions
Die Standard-Handles (stdin, stdout, stderr) sind eigentlich nicht
unbedingt für interaktive Nutzung vorgesehen: Sie können das so
nebenbei, allerdings mit Einschränkungen (wie Du merkst). Die sind
interessant, wenn Pipes oder Redirection des Outputs in Dateien genutzt
werden sollen: Da ist "Datei" eher eine passende Abstraktion.
Heiko L. schrieb:> Vielleicht ist das hier für deine Zwecke besser geeignet:> https://docs.microsoft.com/en-us/windows/console/console-functions
Tatsache... FlushConsoleInputBuffer() ist die Antwort, ganz oben auf der
Liste der Cosole Functions!
Danke für den Link! Darauf kam ich bisher noch nicht.
Dh du würdest davon abraten GetAsyncKeyState() und getch() im gleichen
Code zu verwenden?
lg Llemaban
Llemaban schrieb:> Dh du würdest davon abraten GetAsyncKeyState() und getch() im gleichen> Code zu verwenden?
Ja, auf jeden Fall.
Ich verwende sowas hier:
Frank M. schrieb:> Llemaban schrieb:>> Dh du würdest davon abraten GetAsyncKeyState() und getch() im gleichen>> Code zu verwenden?>> Ja, auf jeden Fall.
Ein grundlegendes Problem dürfte sein, dass die Software blockierend
arbeietn soll, während die Key-Verarbeitung von Windows Event-Gesteuert
ist. Da sind Funktionen wie "Warte auf eine Taste" zumindest
unerwünscht, eigentlich sollten sie verboten sein.
Im konkreten Fall: das Konsolenprogramm wartet auf einen Tastendruck,
der aber nur kommen kann, wenn das Konsolenfenster auch den Focus hat,
sonst bekommt ein anderes Windowsprogramm die Taste. Eine Funktion wie
GetAsyncKeyState() weiss aber garnicht wer den Focus hat. Ist eben das
falsche API an dieser Stelle.
Georg
Danke für die Antworten...
Dann werde ich auf das GetAsyncKeyState verzichten und versuche es
mittels
Frank M. schrieb:> static unsigned short> get_keypress()
einfach auf eine asynchrone Art.
Danke für deinen Code Frank und allen anderen auch :)
Für "format" entsprechend einer der definierten Formate verwenden,
dementsprechend wird der Rückgabewert erstellt.
Ein Rückgabewert von -1 entsteht, wenn der console input buffer leer
ist.
lg Llemaban