2008-09-05 4 views
13

Ich habe eine Konsolen-App, die den Status der Elemente anzeigen muss, aber anstatt Text wie verrückt scrollen zu lassen, würde ich lieber den aktuellen Status in den gleichen Zeilen angezeigt sehen. Aus Gründen des Beispiels:Wie kann ich den gleichen Teil der Konsole in einer nativen Windows C++ - Konsolenanwendung überschreiben, ohne eine Drittanbieterbibliothek zu verwenden?

Running... nn% complete
Buffer size: bbbb bytes

sollte die Ausgabe sein, wobei ‚nn‘ die aktuelle Prozentsatz abgeschlossen ist, und ‚bbbb‘ ist eine Puffergröße, aktualisierte regelmäßig auf dem gleiche Linien der Konsole.

Der erste Ansatz, den ich nahm, druckte einfach die korrekte Anzahl von Rückschritten auf die Konsole, bevor der neue Zustand gedruckt wurde, aber das hat ein widerliches Flimmern, das ich loswerden möchte. Ich möchte auch entweder zu Standard-Bibliothek oder MS-Funktionalität (VC 8) bleiben, um keine weitere Abhängigkeit für diese eine einfache Notwendigkeit einzuführen.

Antwort

8

können Sie SetConsoleCursorPosition verwenden. Sie müssen GetStdHandle aufrufen, um eine Kennung für den Ausgabepuffer zu erhalten.

+0

Siehe meine Antwort für weitere Details, aber für meinen einfachen Fall war dies der einfachste Ansatz. –

0

In Linux können Sie dies erreichen, indem Sie \ b und/oder \ r auf stderr drucken. Möglicherweise müssen Sie experimentieren, um die richtige Kombination von Dingen in Windows zu finden.

5

Wenn Sie mit \ r drucken und keine Funktion verwenden, die einen Zeilenumbruch erzeugt oder \ n zum Ende hinzufügt, springt der Cursor zum Anfang der Zeile zurück und druckt einfach über das nächste, was Sie einfügen oben. Das Erzeugen der kompletten Zeichenfolge vor dem Drucken kann ebenfalls das Flimmern reduzieren.

UPDATE: Die Frage zu 2 Zeilen der Ausgabe wurde anstelle von 1 geändert, die meine Antwort macht nicht mehr vollständig. Ein komplizierterer Ansatz ist wahrscheinlich notwendig. JP hat die richtige Idee mit der Console API. Ich glaube, dass die folgende Website viele der Dinge beschreibt, die Sie benötigen, um Ihr Ziel zu erreichen. Die Website erwähnt auch, dass der Schlüssel zum Reduzieren von Flimmern darin besteht, alles vor dem Anzeigen im Off darzustellen. Dies gilt immer dann, wenn Sie auf dem Bildschirm anzeigen, ob es sich um Text oder Grafiken handelt (2D oder 3D).

http://www.benryves.com/tutorials/?t=winconsole

6

Joseph, JP und CodingTheWheel lieferten wertvolle Hilfe.

Für meinen einfachen Fall des Straight-Forward-Ansatz schien auf CodingTheWheel's answer basieren:

// before entering update loop 
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); 
CONSOLE_SCREEN_BUFFER_INFO bufferInfo; 
GetConsoleScreenBufferInfo(h, &bufferInfo); 

// update loop 
while (updating) 
{ 
    // reset the cursor position to where it was each time 
    SetConsoleCursorPosition(h, bufferInfo.dwCursorPosition); 

    //... 
    // insert combinations of sprintf, printf, etc. here 
    //... 
} 

Für kompliziertere Probleme, die vollen console API als über die mit den Beispielen in Koordination von JP's answer, vorgesehen link von Joseph's answer kann sich als nützlich erweisen, aber ich fand die Arbeit notwendig, CHAR_INFO zu langweilig für solch eine einfache App zu verwenden.

Verwandte Themen