**Konsolengrundgerüst mit Eingabe**
-
Hallo, ich habe in letzter Zeit an der Konsoleneingabe gearbeitet, nur bei mir wird kein getline() zum einlesen verwendet, sondern ich habe eine eigene Lowlevel-Input Funktion geschrieben, die auf folgende Tasten reagiert:
Backspace, ESC, Delete, Return, Leertaste, Cursor bewegen mit Links/Rechts Pfeiltasten. Hierbei kann man noch andere Tasten einbauen wie z.B. TAB, STRG ...
Hier der Code:
#include <windows.h> #include <string> #include <iostream> #include <conio.h> #include "ic.hpp" //Improved Console #pragma comment(lib, "User32.lib") using namespace std; using namespace ic; // Auflösen des Improved Console-Namespace #define ENTER 13 #define BACKSPACE 8 #define LEERTASTE 32 #define ESCAPE 27 #define STEUERZEICHEN 224 #define PFEIL_LINKS 75 #define PFEIL_RECHTS 77 #define DELETE 83 void clearLineAt(string prompt) { cout.put( '\r' ); //Lösche alles ab der Prompt bis zum Ende der Konsole (Improved Console) for( string::size_type i = prompt.length(); i < con.getWndSizeX() ; ++i ) { cout.put( ' ' ); } //cout << prompt << flush; cout << '\r' << prompt << flush; } void gotoxy(short x, short y) { HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hCon, pos); } int main( ) { bool do_exit = false; string prompt = ":\\>"; HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info; do { string input; int key, currentPosition, y; int textpos = 0; cout << prompt; do { key = _getch( ); switch(key) { case BACKSPACE: //Backspace if(textpos > 0) { clearLineAt( prompt ); input.erase(textpos-1, 1 ); cout << input << flush; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; currentPosition = prompt.length() + textpos; gotoxy(currentPosition-1, y); textpos--; } break; case ENTER: //Enter == '\r' cout << "ENTER" << endl; input.append("\0"); break; case LEERTASTE: //Leertaste clearLineAt( prompt ); input.insert(textpos, " "); cout << input << flush; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; break; case ESCAPE: //ESC textpos = 0; clearLineAt( prompt ); input = ""; break; case STEUERZEICHEN: //Steuerzeichen switch( _getch( ) ) { case PFEIL_LINKS: // Pfeiltaste nach Links if(textpos > 0) { GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; currentPosition = prompt.length() + textpos; gotoxy(currentPosition-1, y); textpos--; } break; case PFEIL_RECHTS: // Pfeiltaste nach Rechts: if(textpos < input.length()) { GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } break; case DELETE: //Entfernen Taste if(input.length() != 0) { clearLineAt( prompt ); input.erase(textpos, 1 ); cout << input << flush; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; currentPosition = prompt.length() + textpos; gotoxy(currentPosition, y); } break; } break; default: string tmp; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { clearLineAt( prompt ); tmp = key; input.insert(textpos, tmp); cout << input << flush; } else { input += key; cout.put( key ); } currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; }//Switch() }while( key != ENTER ); cout << endl; if( input.length( ) ) { cout << "Input: " << input << " -> " << textpos << endl << endl; } if( input == "exit" ) { do_exit = true; } } while( !do_exit ); }
So ein Problem besteht immernoch hoffentlich kann mir jemand weiterhelfen, die Funktion clearLineAt() soll eigentlich nur das löschen was hinter der Prompt steht, da mich das Flackern der Prompt bei bestimmten Aktionen stört.
Die Funktion löscht erstmal alles in der Zeile, hier liegt schon das Problem also hoffe jemand hat ne Idee.
-
Kann mir jemand bitte behilflich sein, beim Beseitigen des Flackern der Prompt, ich hab keine Idee
-
Wenn du schon keine eigenen Ideen hast, solltest du wenigstens die Vorschläge ausprobieren, die ich dir schon genannt habe - insbesondere ist es nicht nötig, die Ausgabezeile erstmal mit Leerzeichen zu überpinseln, bevor du sie neu ausgibst (und genau das verursacht das Flackern). Du mußt nur das Endstück der Ausgabezeile übermalen, wenn sie (bei Backspace oder Entf) verkürzt worden ist.
-
Du mußt nur das Endstück der Ausgabezeile übermalen, wenn sie (bei Backspace oder Entf) verkürzt worden ist.
Ich hab nun versucht ohne clearLineAt() zu arbeiten, bei Backspace & Enf müsste auf der Ausgabe das letzte Zeichen gelöscht werden, also hab ich an der Stelle ein cout.put(' ') eingesetzt, doch hier wird wieder input von der aktuellen position ausgegeben, ahhhhhhhhhh
Bei Leerzeichen funktioniert die Ausgabe, nur wenn ich nach links gehe und dann in input ein wort verschieben will wird beim ersten leerzeichen der erste buchstabe vom nächsten wort gelöscht.
case LEERTASTE: //Leertaste //clearLineAt( prompt ); cout.put(' '); input.insert(textpos, " "); //cout << input << flush;
Vielleicht liegt der fehler bei der ausgabe von input, in allen operationen wird input ausgegeben, deshalb überschreibt sich der string immer wieder, der input string ist aber immer richtig nur die Ausgabe ist falsch.
Hoffe du kannst mir bitte weiterhelfen