控制台图形帮助!

发布于 2024-11-08 00:51:56 字数 897 浏览 0 评论 0原文

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

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 ); 
}

In the following code, how am I supposed to create a colored bar at the bottom of the console??
The following code makes the bar at the very top but I wan't to create the bar at the bottom. How am I supposed to do that?

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 ); 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撧情箌佬 2024-11-15 00:51:56

使用 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'å'

这将呈现如下结果:

Win7 x86-64 上的控制台输出

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

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

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

Use GetConsoleScreenBufferInfo to obtain a CONSOLE_SCREEN_BUFFER_INFO structure.

CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(hOutput, &bufferInfo);

You can use srWindow which will give you the coordinates of the corners of the display-window.

Use this to position the bar at the bottom:

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

I am unsure if sr.Window.Left is ever anything but zero, but lets play safe.

Update 1: I used Bottom in rcRegion, it should be Top. I misunderstood the original code.


Now your code has some problems. First, you are using uninitialized memory and write it to the buffer. It will most typically result in hilarious effects.

Second you need to understand that when you write a big region like that straight into the buffer you'll overwrite anything you had there previously. This includes the text you write at the start.

If you want to preserve it you will first need to read from the buffer, alter it and write back.

Anyhow, how to fix the CHAR_BUFFER problem:

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

Zero it. This ensures that every character in the buffer will render a black void where it is written.

Then we need to print out our bar. I use the character for lower case O here.

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

This should be pretty straightforward. You write a o to the last row in the buffer. We also tell it to make it blue. You can use "wide characters" (unicode) instead if you like, UnicodeChar = L'å'.

This will render a result like:

Console output on Win7 x86-64

You can see some of the remaining problems here. Our buffer does not overwrite all of the screen area, leaving some pieces intact (you can see the result from cl.exe there in the margins.)

Why this is should be pretty obvious: SCREEN_* does not correspond to the actual width and height of the window.

Also my prompt ends up in the middle of the block, but that is mainly because our program does not clean up after exit. It is not visible until termination.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文