【问题标题】:Console Graphics Help!控制台图形帮助!
【发布时间】:2011-08-25 21:10:00
【问题描述】:

在下面的代码中,我应该如何在控制台底部创建一个彩色条? 以下代码使栏位于最顶部,但我不想在底部创建栏。我该怎么做?

void main(void)
{
    HANDLE hOutput = (HANDLE)GetStdHandle( STD_OUTPUT_HANDLE ); 
     // Set the text output position to (5,10) 
    COORD sPos; 
    sPos.X = 5; 
    sPos.Y = 10; 
    SetConsoleCursorPosition( hOutput, sPos ); 

    // Set the color to bright green 
    SetConsoleTextAttribute( hOutput, 
    FOREGROUND_INTENSITY | FOREGROUND_GREEN ); 

    // Write the text 
    DWORD nWritten; 
    WriteConsole( hOutput, "This is a test", 14, &nWritten, NULL );

    CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH]; 

    COORD dwBufferSize = { SCREEN_WIDTH,SCREEN_HEIGHT }; 
    COORD dwBufferCoord = { 0, 0 }; 
    SMALL_RECT rcRegion = { 0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 }; 

    WriteConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize, 
        dwBufferCoord, &rcRegion ); 
}

【问题讨论】:

  • Windows 应用程序没有void main() 函数。

标签: c winapi console console-application


【解决方案1】:

使用GetConsoleScreenBufferInfo 获得CONSOLE_SCREEN_BUFFER_INFO 结构。

CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(hOutput, &bufferInfo);

您可以使用srWindow,它将为您提供显示窗口角落的坐标。

使用它来定位底部的栏:

// bufferInfo is a structure CONSOLE_SCREEN_BUFFER_INFO.
SMALL_RECT rcRegion = 
{ 
    bufferInfo.srWindow.Left, 
    bufferInfo.srWindow.Top, 
    SCREEN_WIDTH-1, 
    SCREEN_HEIGHT-1 
}; 

我不确定sr.Window.Left 是否永远不会为零,但让我们谨慎行事。

更新1:我在rcRegion中使用了Bottom,应该是Top。我误解了原始代码。


现在您的代码有一些问题。首先,您正在使用未初始化的内存并将其写入缓冲区。它通常会产生搞笑的效果。

其次,您需要了解,当您将这样的大区域直接写入缓冲区时,您将覆盖以前在那里的任何内容。这包括您在开始时编写的文本。

如果你想保留它,你首先需要从缓冲区中读取,改变它并写回。

无论如何,如何解决CHAR_BUFFER 问题:

CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH]; 
memset(&buffer, 0, sizeof(buffer));

归零。这样可以确保缓冲区中的每个字符都会在写入的位置呈现黑色空白。

然后我们需要打印出我们的酒吧。我在这里使用小写 O 的字符。

for (int i = 0; i < SCREEN_WIDTH; i++)
{
    buffer[SCREEN_HEIGHT - 1][i].Char.AsciiChar = 'o';
    buffer[SCREEN_HEIGHT - 1][i].Attributes = FOREGROUND_BLUE;
}

这应该很简单。您将o 写入缓冲区的最后一行。我们还告诉它让它变成蓝色。如果你愿意,你可以使用“宽字符”(unicode),UnicodeChar = L'å'

这将呈现如下结果:

您可以在此处查看剩余的一些问题。我们的缓冲区不会覆盖所有的屏幕区域,保留一些完整的部分(您可以在边缘看到来自cl.exe 的结果。)

为什么这应该很明显:SCREEN_* 不对应窗口的实际宽度和高度。

我的提示也出现在块的中间,但这主要是因为我们的程序在退出后没有清理。在终止之前它是不可见的。

【讨论】:

  • 我仍然无法让它工作。请您详细给出代码....这就是我正在做的事情:CONSOLE_SCREEN_BUFFER_INFO bufferInfo; bufferInfo.srWindow.Left=0; bufferInfo.srWindow.Bottom=25; GetConsoleScreenBufferInfo(hOutput, &amp;bufferInfo);
  • @Spoilt:我的想法有误。我也知道为什么它不起作用。请稍等,我会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 2011-11-27
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多