Wie funktioniert die TAB-Vervollständigung bei cmd.exe ???
-
Hallo, ich habe eine Konsolenanwendung geschrieben mit der man in Verzeichnise wechseln kann, wie z.B. cd c:\test
Hier der Code:
#include <windows.h> #include <iostream> #include <string> #include <tchar.h> #include <sstream> #include <vector> #include <Shlwapi.h> using namespace std; #pragma comment(lib, "Shlwapi.lib") string ApplicationDirectory(); //***Global*** string Pfad = ApplicationDirectory(); string ApplicationDirectory() { TCHAR szPathName[_MAX_PATH]; ::GetModuleFileName(NULL, szPathName, _MAX_PATH); LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1; *pszFileName = '\0'; return szPathName; } int checkDir(string str) { if (PathIsDirectory(str.c_str())) return 1; else return 0; } //Ausgabe Prompt void prompt() { //cout << Pfad << ">>"; char ps[100]; GetCurrentDirectory(90, ps); cout << endl << ps << ">"; } int main() { string str; do { //Setzt den aktuellen Pfad SetCurrentDirectory(Pfad.c_str()); prompt(); getline(cin, str); istringstream cmdline (str); string input; vector<string> params; string tmp; while (cmdline >> tmp) { params.push_back (tmp); } if(params.size() >= 2) { if(params[0] == "cd") { //Pfad = params[1]; if(checkDir(params[1]) == 1) { Pfad = params[1]; } else cout << "Verzeichnis '" << params[1] << "' nicht gefunden" << endl << endl; } } if(params.size() >= 1) { if(params[0] == "exit") return 0; if(params[0] == "dir") system("dir"); } }while(1); return 0; }Jeder oder einige von euch kennen wenn man in cmd ein Verzeichnis nicht ganz eingibt und dann Tab drückt, werden alle mit dem angefangen Verzeichnis oder Dateien ausgegeben, so kann man schneller in Verzeichnise wechseln.
Jetzt wollte ich fragen wie funktioniert die TAB-Vervollständigung in cmd, wie wurde sie implementiert, ist es möglich sowas zu realisieren????
-
Naja, damit du möglichst schnell das Ergebnis bekommst, solltest du alle Verzeichnisse vorher in einen Baum speichern und dann ist das ein einfacher string vergleich und der string der passt wird ausgewählt. Sollte relative leicht zu implementieren st. Ansonsten kannst du dir ja irgendeine Shell ankucken wie die es dort gemacht haben.
-
Mit den normalen Eingabe Funktionen wie getline() kann sowas doch nicht klappen, es muss ja ganze Zeit gewartet werden das vielleicht die TAB Taste gedrückt wird, erst dann soll die Eingegebene Zeile Vervollständigt werden.
Wie sieht der Aufbau so einer Funktion aus???
Bitte um Hilfe!!!!
-
Mit SetConsoleMode den Line-Input Modus abstellen und dann ReadConsole(Input).
-
So habe folgenden Code zusammengebastelt:
#include <windows.h> #include <stdio.h> #include <iostream> #include <string> using namespace std; VOID ErrorExit(LPSTR); VOID KeyEventProc(KEY_EVENT_RECORD); int main(VOID) { cout << "Eingabe:>"; HANDLE hStdin; DWORD cNumRead, fdwMode, fdwSaveOldMode, i; INPUT_RECORD irInBuf[128]; int counter=0; // Get the standard input handle. hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) ErrorExit(TEXT("GetStdHandle")); // Save the current input mode, to be restored on exit. if (! GetConsoleMode(hStdin, &fdwSaveOldMode) ) ErrorExit(TEXT("GetConsoleMode")); // Enable the window and mouse input events. fdwMode = ENABLE_WINDOW_INPUT; if (! SetConsoleMode(hStdin, fdwMode) ) ErrorExit(TEXT("SetConsoleMode")); // Loop to read and handle the input events. while (counter++ <= 100) { // Wait for the events. if (! ReadConsoleInput( hStdin, // input buffer handle irInBuf, // buffer to read into 128, // size of read buffer &cNumRead) ) // number of records read ErrorExit(TEXT("ReadConsoleInput")); // Dispatch the events to the appropriate handler. for (i = 0; i < cNumRead; i++) { switch(irInBuf.EventType) { case KEY_EVENT: // keyboard input KeyEventProc(irInBuf[i].Event.KeyEvent); break; } } } return 0; } VOID ErrorExit (LPSTR lpszMessage) { fprintf(stderr, "%s\n", lpszMessage); ExitProcess(0); } VOID KeyEventProc(KEY_EVENT_RECORD ker) { //Wartet auf TAB Taste if(ker.wVirtualKeyCode == VK_TAB) { if(ker.bKeyDown) cout << "#TAB EVENT PRESSED#"; else cout << "#TAB EVENT RELEASED#"; } //Normale Eingabe else { //hier kommt die normale eingabe cout << "#Ausgabe#" << endl; } }Das Programm wartet auf bestimmte Key Events, in der Funktion [i]KeyEventProc()* wird geprüft ob die TAB Taste gedrückt wird.
Wenn ich nun einmal TAB drücke, wird einmal die PRESSED und die RELEASED funktion ausegeben, obwohl ich nur einmal gedrückt habe, bei anderen Eingaben wird auch die Ausgabe zweimal ausgegeben, wo liegt der Fehler??Jetzt kommt die große Frage, wenn ich nicht die TAB Taste drücke, dann sollen erstmal die Eingaben ausgegeben werden wie bei getline(), wie macht man das???
-
Habe die Funktion erweitert:
VOID KeyEventProc(KEY_EVENT_RECORD ker) { //Wartet auf TAB Taste if(ker.wVirtualKeyCode == VK_TAB) { if(ker.bKeyDown) cout << "#TAB EVENT PRESSED#"; else cout << "#TAB EVENT RELEASED#"; } //Wartet auf Enter Taste if(ker.wVirtualKeyCode == VK_RETURN) { cout << "NEWLINE" << endl; cout << "INPUT: " << input << endl; //Input löschen input.clear(); } //Normale String Eingabe else { input += ker.uChar.AsciiChar; } }-
Wenn ich etwas eingebe dann sehe ich sie nicht in der Console, wie kann ich die Eingaben sichtbar machen?
-
Wieso wird jedes eingegeben Zeichen doppelt gespeichert, wegen dem PRESSSED und RELEASED????
Bitte um Hilfe!!!!!!
-
-
Habe noch einiges verändert, das mit den doppelten Zeichen habe ich beseitigt:
#include <windows.h> #include <stdio.h> #include <iostream> #include <string> using namespace std; //Eingabe String string input = ""; VOID ErrorExit (LPSTR lpszMessage) { fprintf(stderr, "%s\n", lpszMessage); ExitProcess(0); } //VOID KeyEventProc(KEY_EVENT_RECORD ker, HANDLE hStdin, DWORD fdwSaveOldMode) VOID KeyEventProc(KEY_EVENT_RECORD ker) { //Wartet auf TAB Taste if(ker.wVirtualKeyCode == VK_TAB) { if(ker.bKeyDown) cout << "#TAB EVENT PRESSED#"; else cout << "#TAB EVENT RELEASED#"; } //Wartet auf Enter Taste else if(ker.wVirtualKeyCode == VK_RETURN) { cout << "NEWLINE" << endl; cout << input << endl; //Input löschen input.clear(); } if(ker.wVirtualKeyCode == VK_BACK) { cout << "löschen" << endl; } //Normale String Eingabe else { //Alte Einstellungen wiederherstellen //SetConsoleMode(hStdin, fdwSaveOldMode); if(ker.bKeyDown){} else { cout << "Zeichen: " << ker.uChar.AsciiChar << endl; input += ker.uChar.AsciiChar; } } } int ReadKeyInput() { HANDLE hStdin; DWORD cNumRead, fdwMode, fdwSaveOldMode, i; INPUT_RECORD irInBuf[128]; int counter=0; // Get the standard input handle. hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) ErrorExit(TEXT("GetStdHandle")); // Save the current input mode, to be restored on exit. if (! GetConsoleMode(hStdin, &fdwSaveOldMode) ) ErrorExit(TEXT("GetConsoleMode")); // Enable the window and mouse input events. fdwMode = ENABLE_WINDOW_INPUT; if (! SetConsoleMode(hStdin, fdwMode) ) ErrorExit(TEXT("SetConsoleMode")); // Loop to read and handle the input events. while (counter++ <= 100) //while(1) { // Wait for the events. //if(!ReadConsole(hStdin, irInBuf, 128, &cNumRead, NULL)) // ErrorExit(TEXT("ReadConsole")); if (! ReadConsoleInput( hStdin, // input buffer handle irInBuf, // buffer to read into 128, // size of read buffer &cNumRead) ) // number of records read ErrorExit(TEXT("ReadConsoleInput")); // Dispatch the events to the appropriate handler. for (i = 0; i < cNumRead; i++) { switch(irInBuf[i].EventType) { case KEY_EVENT: // keyboard input //KeyEventProc(irInBuf[i].Event.KeyEvent, hStdin, fdwSaveOldMode); KeyEventProc(irInBuf[i].Event.KeyEvent); break; } } } return 0; } int main(VOID) { ReadKeyInput(); return 0; }Ist es überhaupt möglich mit der ReadConsoleInput() Funktion die Eingaben auch auszugeben, denn bei MSDN steht das nur die ReadConsole() Funktion das kann, bitte seht selbst vielleicht hab ich es nicht verstanden: http://msdn2.microsoft.com/en-us/library/ms686033.aspx
ENABLE_ECHO_INPUT - Characters read by the ReadFile or ReadConsole function are written to the active screen buffer as they are read. This mode can be used only if the ENABLE_LINE_INPUT mode is also enabled.
Also irgendwie glaube ich in
cmd.exesteckt eine andere funktionsweise, bitte gibt mir weitere Verbesserungsvorschläge/Tipps sonst komme ich nicht weiter

-
Ich frage jetzt ein letztes mal, kann man die TAB Funktion mit der WinAPI realisieren oder wie hat es Microsoft geschafft ????????????????