如何在不使用 3rd Party 库的情况下覆盖 Windows 本机 C++ 控制台应用程序中控制台的相同部分?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I overwrite the same portion of the console in a Windows native C++ console app, without using a 3rd Party library?
提问by Patrick Johnmeyer
I have a console app that needs to display the state of items, but rather than having text scroll by like mad I'd rather see the current status keep showing up on the same lines. For the sake of example:
我有一个控制台应用程序需要显示项目的状态,但与其让文本像疯了一样滚动,我宁愿看到当前状态继续显示在同一行上。举个例子:
Running... nn% complete
Buffer size: bbbb bytes
Running... nn% complete
Buffer size: bbbb bytes
should be the output, where 'nn' is the current percentage complete, and 'bbbb' is a buffer size, updated periodically on the same lines of the console.
应该是输出,其中 'nn' 是当前完成百分比,'bbbb' 是缓冲区大小,在控制台的同一行上定期更新。
The first approach I took simply printed the correct number of backspaces to the console before printing the new state, but this has an obnoxious flicker that I want to get rid of. I also want to stick to either standard library or MS-provided functionality (VC 8) so as not to introduce another dependency for this one simple need.
我采用的第一种方法只是在打印新状态之前将正确数量的退格符打印到控制台,但这有一个令人讨厌的闪烁,我想摆脱它。我还想坚持使用标准库或 MS 提供的功能 (VC 8),以免为这个简单的需求引入另一个依赖项。
采纳答案by Patrick Johnmeyer
You can use SetConsoleCursorPosition. You'll need to call GetStdHandleto get a handle to the output buffer.
您可以使用SetConsoleCursorPosition。您需要调用GetStdHandle来获取输出缓冲区的句柄。
回答by Patrick Johnmeyer
Joseph, JP, and CodingTheWheel all provided valuable help.
Joseph、JP 和 CodingTheWheel 都提供了宝贵的帮助。
For my simple case, the most straight-forward approach seemed to be based on CodingTheWheel's answer:
对于我的简单案例,最直接的方法似乎是基于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
//...
}
For more complicated problems, the full console APIas provided by JP's answer, in coordination with the examples provided via the linkfrom Joseph's answermay prove useful, but I found the work necessary to use CHAR_INFO
too tedious for such a simple app.
对于更复杂的问题,充分控制台API通过提供JP的回答,与通过提供的例子协调链接从约瑟夫的回答可能是有用的,但我认为有必要在工作中使用CHAR_INFO
过于繁琐这样一个简单的应用程序。
回答by Joseph
If you print using \r and don't use a function that will generate a newline or add \n to the end, the cursor will go back to the beginning of the line and just print over the next thing you put up. Generating the complete string before printing might reduce flicker as well.
如果您使用 \r 打印并且不使用会生成换行符或在末尾添加 \n 的函数,则光标将返回到该行的开头并只打印您放置的下一个内容。在打印之前生成完整的字符串也可以减少闪烁。
UPDATE: The question has been changed to 2 lines of output instead of 1 which makes my answer no longer complete. A more complicated approach is likely necessary. JP has the right idea with the Console API. I believe the following site details many of the things you will need to accomplish your goal. The site also mentions that the key to reducing flicker is to render everything offscreen before displaying it. This is true whenever you are displaying anything on the screen whether it is text or graphics (2D or 3D).
更新:问题已更改为 2 行输出而不是 1 行,这使我的答案不再完整。可能需要更复杂的方法。JP 对Console API有正确的想法。我相信以下站点详细介绍了实现目标所需的许多事情。该网站还提到减少闪烁的关键是在显示之前将所有内容渲染到屏幕外。无论何时在屏幕上显示任何内容,无论是文本还是图形(2D 或 3D),都是如此。
回答by Johannes Passing
In case the Joseph's suggestion does not give you enough flexibility, have a look at the Console API: http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx.
如果约瑟夫的建议没有给您足够的灵活性,请查看控制台 API:http: //msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx。
回答by Ben Collins
In Linux, you can accomplish this by printing \b and/or \r to stderr. You might need to experiment to find the right combination of things in Windows.
在 Linux 中,您可以通过将 \b 和/或 \r 打印到 stderr 来完成此操作。您可能需要尝试在 Windows 中找到正确的组合。