Как я могу перезаписать ту же часть консоли в собственном консольном приложении C++ для Windows без использования сторонней библиотеки?

У меня есть консольное приложение, которое должно отображать состояние элементов, но вместо того, чтобы прокручивать текст как сумасшедший, я бы предпочел, чтобы текущий статус продолжал отображаться в одних и тех же строках. Для примера:

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

должен быть выводом, где «nn» — текущий процент выполнения, а «bbbb» — размер буфера, периодически обновляемый в тех же строках консоли.

Первый подход, который я использовал, просто печатал правильное количество пробелов в консоли перед печатью нового состояния, но у этого есть неприятное мерцание, от которого я хочу избавиться. Я также хочу придерживаться либо стандартной библиотеки, либо функций, предоставляемых MS (VC 8), чтобы не вводить еще одну зависимость для этой простой потребности.


person Patrick Johnmeyer    schedule 05.09.2008    source источник


Ответы (5)


Вы можете использовать SetConsoleCursorPosition. Вам потребуется вызвать GetStdHandle, чтобы получить дескриптор выходного буфера. .

person Community    schedule 05.09.2008
comment
Смотрите мой ответ для более подробной информации, но для моего простого случая это был самый простой подход. - person Patrick Johnmeyer; 08.09.2008

Joseph, JP и CodingTheWheel оказали ценную помощь.

Для моего простого случая самый простой подход, казалось, был основан на Ответ CodingTheWheel:

// 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
  //...
}

Для более сложных проблем используйте полный API консоли, предоставленный Ответ JP в соответствии с примерами, предоставленными по ссылке от Ответ Джозефа может оказаться полезным, но я нашел работу, необходимую для использования CHAR_INFO, слишком утомительной для такого простого приложения.

person Patrick Johnmeyer    schedule 08.09.2008

Если вы печатаете с помощью \r и не используете функцию, которая будет генерировать новую строку или добавлять \n в конец, курсор вернется к началу строки и просто напечатает следующее, что вы поместите. Генерация полной строки перед печатью также может уменьшить мерцание.

ОБНОВЛЕНИЕ: вопрос был изменен на 2 строки вывода вместо 1, что делает мой ответ более неполным. Вероятно, необходим более сложный подход. У JP правильная идея с Console API . Я считаю, что на следующем сайте подробно описаны многие вещи, которые вам понадобятся для достижения вашей цели. На сайте также упоминается, что ключом к уменьшению мерцания является рендеринг всего за кадром перед его отображением. Это верно всякий раз, когда вы отображаете что-либо на экране, будь то текст или графика (2D или 3D).

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

person Joseph    schedule 05.09.2008

Если предложение Джозефа не дает вам достаточной гибкости, взгляните на консольный API: http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx.

person Johannes Passing    schedule 05.09.2008

В Linux это можно сделать, напечатав \b и/или \r в stderr. Возможно, вам придется поэкспериментировать, чтобы найти правильное сочетание вещей в Windows.

person Ben Collins    schedule 05.09.2008