Artery Geschrieben 18. April 2011 Teilen Geschrieben 18. April 2011 hi, wie frage ich ab ob eine taste gedrückt gehalten wird? Ich hab eine Schleife mit while(_kbhit()== 0) wenn jetzt jemand eine taste gedrückt hält bekomme ich probleme und es passiert nichts mehr in der Schleife kommt erstmal folgendes: tmp = _getch(); if(_kbhit() == 1) { if(tmp != -32) { while(_kbhit() == 1) { _getch(); } } } das sorgt nur dafür, das wenn andere Tasten gleichzeitig gedrückt werden, diese sozusagen ignoriert werden, im rest der Schleife sind nur noch if-abfragen... Zusagen ist noch, das man sich nur mit den Pfeiltasten nach oben und unten bewegen kann! Woran liegt das jetzt das dann nichts mehr passiert, er scheint dann zu hängen, da er nicht mehr auf Eingaben reagiert, wie kann ich das jetzt beheben?? MfG Artery Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Crash2001 Geschrieben 18. April 2011 Teilen Geschrieben 18. April 2011 Es gibt Tasten bzw. auch Tastenkombinationen, denen kein Ascii-/Ansi-Code zugewiesen wurde (berühmtestes Beispiel hierfür sind wohl die Pfeiltaste ). Funktionen wie deine geben in solchen Fällen Sondercodes zurück. Ob diese dann korrekt ausgewertet werden (können) ist dann halt die Frage. Schau mal dazu z.B. hier bzw zu dem Forenbereich hier. Vielleicht hilft dir das ja weiter. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Artery Geschrieben 18. April 2011 Autor Teilen Geschrieben 18. April 2011 Ich habe es schon implementiert, das man sich mit den Pfeiltasten bewegen kann, das ist ja nicht das Problem Sondern wenn ich jetzt z.b "Pfeiltaste nach unten" gedrückt halte, macht er noch kurz so weiter wie er sollte und ihrgendwann harkt er dann und macht nichts mehr! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 18. April 2011 Teilen Geschrieben 18. April 2011 while(_kbhit() == 1) { _getch(); }[/code]Solange eine Taste gedrückt wurde, liest du den Zeichencode aus. Ansonsten passiert in der Schleife nichts. Was willst du denn damit erreichen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Artery Geschrieben 18. April 2011 Autor Teilen Geschrieben 18. April 2011 (bearbeitet) Wenn jetzt jemand 2 oder mehr tastengleichzeitig drückt kam es zu problemen, damit werden einfach alle anderen Tasten aus dem inbuffer genommen. was evt noch von interesse wäre ist das: So ungefähr sieht die Schleife aus, das unwichtige hab ich rausgelassen while(1) { while(_kbhit()== 0) { tmp = _getch(); if(_kbhit() == 1) { if(tmp != -32) { while(_kbhit() == 1) { _getch(); } } } if() { ....... } else if(tmp == -32) { tmp2 = _getch(); if(tmp == -32 && tmp2 == 72 || tmp == -32 && tmp2 == 80) { } } Edit: was mir noch einfällt er springt immer in eine Funktion in einer anderen Quelldatei, wenn die Pfeiltasten gedrückt wurden, könnte es ein das ert deswegen iwann hängt? Bearbeitet 18. April 2011 von Artery Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 18. April 2011 Teilen Geschrieben 18. April 2011 Steckt da irgendeine Planung dahinter, oder ist der Code durch Ausprobieren entstanden? Wenn du nicht weißt, wo und warum es hängt, wie kannst du dann beurteilen, was "unwichtig" ist und daher weggelassen werden kann? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Artery Geschrieben 18. April 2011 Autor Teilen Geschrieben 18. April 2011 Der code ist deswegen unwichtig, weil er nur greift, wenn andere Tasten gedrückt werden deswegen hab ich das weggelassen, weil es nicht eintritt! Aber ich kann gerne den ganzen code posten wenn du willst: while(1) { while(_kbhit()== 0) // Die Schleife greift, wenn eine Taste gedrückt wurde { i = 0; sprintf(Profilnameraw,"<<<<<<<<<<<<<<<"); tmp = _getch(); // Das erste Zeichen des Puffer wird genommen und in tmp geschrieben if(tmp == 27) // Wird escape gedrückt, wird das Programm sofort beendet { exit(1); } if(_kbhit() == 1) // Sollte immer noch eine Taste gedrückt sein, das heißt, das entweder Sie noch ein Vorzeichen hat, oder mehrere Tasten gedrückt wurden, springt er in die If-Abfrage { if(tmp != -32) // Wenn es sich nicht um das Vorzeichen -32 handelt soll er die While-Schleife ausführen { while(_kbhit() == 1) // Die While-Schleife leert den Puffer bis keine Eingabe mehr vorhanden ist { _getch(); } } } if(ButtonCrsLoc == 0 && tmp == 13) { Optionen_Menü_main(); } else if(VoidProfil == true && tmp == 'e') // Wenn der 'Cursor' gerade auf einem leeres Profil zeigt, und 'e' gedrückt wurde, dann wird in das if gesprugen { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Bitte geben Sie den Namen des Profils ein und bestätigen Sie ihre Eingabe mit Enter. Der Name darf nicht die Zeichen '<' und '>' beinhalten und darf nur 15 Zeichen lang sein!", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder(" ", ic::FG_LIGHTBLUE,5,12, 7,12,YWert[ButtonCrsLoc],24, NULL, NULL, 30, true); SetCursor(5,12,0,YWert[ButtonCrsLoc],24,true,true); Profil_Menü_Button_Namen_ändern(YWert,ButtonCrsLoc,edit_tmp,i,i2,Profile,Profilnameraw,VoidProfil,ProfilText); } else if(VoidProfil == false && tmp == 'e' || VoidProfil == false && tmp == 'd' || VoidProfil == false && tmp == 13) { if(tmp == 'd') { while(_kbhit() == 1) // Der Puffer wird geleert { _getch(); } Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Möchten Sie wirklich dieses Profil löschen? Zum bestätigen drücken Sie 'enter', wenn nicht 'escape'!", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); while(_kbhit() == 0) { edit_tmp = _getch(); while(_kbhit() == 1) { _getch(); } if(edit_tmp == 27) { sprintf(ProfilText, "Dies ist das Profil von: %s , Sie können dieses nun löschen 'd', editieren 'e' oder betreten mit 'enter'",Profile[ButtonCrsLoc-1].Profil_Name); Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder(ProfilText, ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); break; } else if(edit_tmp == 13) { i = 0; while(i != 15) { Profile[(ButtonCrsLoc-1)].Profil_Name[i] = '\0'; i++; } sprintf(Profile[(ButtonCrsLoc-1)].Profil_Name, "<LEER>"); ProfileVTPro = fopen("Profile.VTPro", "wb"); fwrite(Profile,sizeof(struct ProfilStruct),6,ProfileVTPro); fclose(ProfileVTPro); SetCursor(5,12,0,YWert[ButtonCrsLoc],24,false,true); std::cout << " "; Text_Builder(" ", ic::FG_LIGHTBLUE,5,12, 7,12,YWert[ButtonCrsLoc],24, NULL, NULL, 30, true); Text_Builder(Profile[(ButtonCrsLoc-1)].Profil_Name, ic::FG_LIGHTBLUE,5,12,7,12,YWert[ButtonCrsLoc],24, NULL, NULL, 30, true); Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Dieses Profil ist leer, Sie können ein neues erstellen, drücken Sie dazu 'e'", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); VoidProfil = true; break; } } } else if(tmp == 'e') { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Bitte geben Sie den Namen des Profils ein und bestätigen Sie ihre Eingabe mit Enter. Der Name darf nicht die Zeichen '<' und '>' beinhalten und darf nur 15 Zeichen lang sein!", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder(" ", ic::FG_LIGHTBLUE,5,12, 7,12,YWert[ButtonCrsLoc],24, NULL, NULL, 30, true); SetCursor(5,12,0,YWert[ButtonCrsLoc],24,true,true); Profil_Menü_Button_Namen_ändern(YWert,ButtonCrsLoc,edit_tmp,i,i2,Profile,Profilnameraw,VoidProfil,ProfilText); } else if(tmp == 13) { exit(1); } } else if(tmp == -32) // Wenn eine Taste mit dem Vorzeichen -32 , z.B. eine Pfeiltaste, springt er in das else if { tmp2 = _getch(); if(tmp == -32 && tmp2 == 72 || tmp == -32 && tmp2 == 80) { tmp = tmp2; if(tmp == 80) { if(ButtonCrsLoc == 6) { ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,true,0); ButtonCrsLoc = 0; ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,false,0); } else { ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,true,0); ButtonCrsLoc = ButtonCrsLoc + 1; ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,false,0); } } if(tmp == 72) { if(ButtonCrsLoc == 0) { ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,true,0); ButtonCrsLoc = 6; ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,false,0); } else { ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,true,0); ButtonCrsLoc = ButtonCrsLoc - 1; ArrowBuilder(3,12,YWert[ButtonCrsLoc],24,false,0); } } if(ButtonCrsLoc == 0) { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Öffnet das Optionenmenü! (enter)", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, NULL, NULL, 0, true); } else if(Profile[ButtonCrsLoc-1].Profil_Name[0] == '<') { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Dieses Profil ist leer, Sie können ein neues erstellen, drücken Sie dazu 'e'", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); VoidProfil = true; } else if(Profile[ButtonCrsLoc-1].Profil_Name != "<LEER>") { sprintf(ProfilText, "Dies ist das Profil von: %s , Sie können dieses nun löschen 'd', editieren 'e' oder betreten mit 'enter'",Profile[ButtonCrsLoc-1].Profil_Name); Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder(ProfilText, ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); VoidProfil = false; } } } } } So das ist die gesamte Schleife... Ich hoffe ihr könnt damit was anfangen! MfG Artery Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Crash2001 Geschrieben 18. April 2011 Teilen Geschrieben 18. April 2011 Also ich habe mir den Quellcode jetzt nicht ganz durchgelesen (grad keine Zeit für), aber in dem Beispiel was ich gesehen hatte, war ein Timer drin, so dass nicht durchgehend abgefragt wurde, sondern Abfrage, x Millisekunden Pause und dann erst die nächste Abfrage. Eventuell überlädt da ja irgendetwas, oder aber die CPU-Last geht so weit hoch, dass nichts anderes mehr gemacht wird bei dir. (Nur eine Vermutung / Überlegung) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Artery Geschrieben 18. April 2011 Autor Teilen Geschrieben 18. April 2011 Timer? Wo meinst du genau? Die einzigsten Befehle mit sleep > 0 werden nur dann ausgeführt, wenn man sich sowieso gerade nicht mit den Pfeiltasten bewegen kann.. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Artery Geschrieben 18. April 2011 Autor Teilen Geschrieben 18. April 2011 Ich weiß jetzt woran es liegt, und zwar daran if(ButtonCrsLoc == 0) { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Öffnet das Optionenmenü! (enter)", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, NULL, NULL, 0, true); } else if(Profile[ButtonCrsLoc-1].Profil_Name[0] == '<') { Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder("Dieses Profil ist leer, Sie können ein neues erstellen, drücken Sie dazu 'e'", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); VoidProfil = true; } else if(Profile[ButtonCrsLoc-1].Profil_Name != "<LEER>") { sprintf(ProfilText, "Dies ist das Profil von: %s , Sie können dieses nun löschen 'd', editieren 'e' oder betreten mit 'enter'",Profile[ButtonCrsLoc-1].Profil_Name); Text_Builder(" ", ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); Text_Builder(ProfilText, ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); VoidProfil = false; } Deswegen hängt er, denn hinter Text_Builder(ProfilText, ic::FG_LIGHTBLUE, 3, 12, 9, 12, 1, 24, 5, 24, 0, false); versteckt sich ne etwas umfangreiche funktion und die ist der Grund dafür :/ Die Funktion: void Text_Builder(char Text[], ic::TextColor color, int X10, int X01, int X20, int X02, int Y10, int Y01,int YE10, int YE01, int sleeptime, bool Button) // Die Funktion gibt einen Text an der angegeben Stelle aus und unterteilt ihn "intelligent" in Zeilen. Die Funktion "erstellt" Rechtecke mit den gewünschten Eckdaten. Übergeben wird: Der Text, sowie die Textfarbe. X-Anfangs-, X-End, Y-Anfangswertw als 'Brüche' übergeben, z.b. X10 und X01 ergeben 2/12, das ist der Anfangswert und der Bruch aus X20, X02 ist der Bruch für den Endwert, ggf. werden auch die Y-Endwerte als Bruch übergeben. Dann wird noch die sleeptime übergeben, d.h. wie lang pause zwischen den Einzelnenzeichen gesetzt soll. Und auch ob es sich um einen Button handelt, da dann eine kleine Änderung an dem Y-Wert vorgenommen werden muss. { if(YE10 != NULL && YE01 != NULL) //Sollte YE10, sowie YE01 gleich "NULL" sein, das bedeutet, der Text ist nur eine Zeile lang, springt das Programm in das else, wenn beide einen Wert haben, also der Text länger als eine Zeile ist, geht es in der If-Bedingung weiter { int Textrestlen = strlen(Text); int Zeilen = 1; // Steht von Anfang an auf 1, da sowieso mindestens eine Zeile gebraucht wird int iadd; int k = 0; int counter2 = 0; int counter = 0; int* Zeileninhalt = NULL; //Zeiger (Adresse) für späteres dynamisches Array sichern int* Zeilenreduce = NULL; while(Textrestlen >= ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) *(-1)) // Rechnet die Anzahl der benötigten Zeilen, sowie die Textrestlänge (Wie viele Zeichen in eine neue, nicht komplett befüllte Zeile kommen) { Textrestlen = Textrestlen - ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) *(-1); Zeilen++; } Zeileninhalt = new int [Zeilen]; //Anlegen eines dynamischen Arrays Zeilenreduce = new int [Zeilen]; counter2 = ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) *(-1); for(int i = 1; i <= Zeilen;i++) // Berechnung der Anzahl der Zeichen in einer Zeile { if((counter + ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) *(-1)) <= strlen(Text)) { for(int j = counter2; ;j--) { if(Text[j] == 32 || Text[j] == 44 || Text[j] == 46 || Text[j] == 33) // Bei Punkten, Kommata, Ausrufezeichen und Leerzeichen, kann ein Zeilenumbruch entstehen { Zeileninhalt[k] = j - counter; Zeilenreduce[k] = j - counter; counter = j; counter2 = j + ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) *(-1); k++; break; } } } else { Zeileninhalt[k] = strlen(Text) - counter; Zeilenreduce[k] = strlen(Text) - counter; } } counter = 0; k = 0; ic::con.setTextColor(color); // Setzt die Textfarbe auf die Übergebene for(int i = 0; i <= Zeilen ; i++) // Rechnet iadd aus und "springt" sozusagen in die nächste Zeile { iadd = ( ((DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02)) - (Zeileninhalt[i]+1)); // In "iadd" steht die Größe des Abstandes zu den Rändern um den Text zu zentrieren (Ist der Abstand ungerade entsteht hier eine kleine ungenauigkeit!) if(iadd % 2 == 0) { iadd = iadd /2; } else { iadd= (iadd -1) /2; } if(i != 0) { counter = counter + Zeileninhalt[k]; k++; } for(int j = DEF_WNDSIZEX * X20/X02 + 1 + iadd; j <= DEF_WNDSIZEX * X10/X01 - iadd; j++) // Gibt den Text aus { if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == ' ' && j == DEF_WNDSIZEX * X20/X02 + 1 + iadd) // Sollte das Erste Zeichen der neuen Zeile ein Leerzeichen sein, wird es weggelassen { j++; Zeilenreduce[k]--; } if(Zeilenreduce[k] == 0 && Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == ' ' ) //Ist das letzte Zeichen einer Zeile ein Leerzeichen wird es weggelassen { break; } ic::con.setCurPos (j, DEF_WNDSIZEY * (Y10+k)/Y01 + 1); if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'ö') // Umlaute werden korrekt umgewandelt { std::cout << char(148); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'ü') { std::cout << char(129); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'ä') { std::cout << char(132); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'ß') { std::cout << char(225); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'Ö') { std::cout << char(153); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'Ä') { std::cout << char(142); } if(Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)] == 'Ü') { std::cout << char(154); } else { std::cout << Text[(Zeileninhalt[k]-Zeilenreduce[k]+counter)]; } Zeilenreduce[k]--; Sleep(sleeptime); } } delete[] Zeileninhalt; // Speicherplatz wiederfreigeben um Memory leaks zu vermeiden delete[] Zeilenreduce; Zeileninhalt = NULL; Zeilenreduce = NULL; } else { int k=0; int iadd; ic::con.setTextColor(color); // Setzt die Textfarbe auf die übergebene Farbe iadd = ( (DEF_WNDSIZEX * X10/X01) - (DEF_WNDSIZEX *X20/X02) - strlen(Text)) / 2; // In "iadd" steht die Größe des Abstandes zu den Rändern um den Text zu zentrieren (Ist der Abstand ungerade entsteht hier eine kleine ungenauigkeit!) for(int i = DEF_WNDSIZEX * X20/X02 + 1 + iadd; i <= DEF_WNDSIZEX * X10/X01 - iadd; i++) // Gibt den Text aus { if(Button == true) // Da die Texte für "Buttons" nicht zentriert sind, und die in normalen Fenster es schon seien sollen, muss hier nochmal extra abgefragt werden, um was es sich handelt { ic::con.setCurPos (i, DEF_WNDSIZEY * Y10/Y01 + 1); } else { ic::con.setCurPos (i, DEF_WNDSIZEY * Y10/Y01); } if(k == (strlen(Text))) { break; } if(Text[k] == 'ö') // Umlaute werden korrekt umgewandelt { std::cout << char(148); } if(Text[k] == 'ü') { std::cout << char(129); } if(Text[k] == 'ä') { std::cout << char(132); } if(Text[k] == 'ß') { std::cout << char(225); } if(Text[k] == 'Ö') { std::cout << char(153); } if(Text[k] == 'Ä') { std::cout << char(142); } if(Text[k] == 'Ü') { std::cout << char(154); } else { std::cout << Text[k]; } k++; Sleep(sleeptime); } } } Wäre schön wenn ihr nochmal drüber guckt, vielleicht krieg ich die Funktion noch so angepasst das es klappt :/ MfG Artery Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.