RGB特定控制台文本颜色C++

12
我正在尝试将win32控制台应用程序的字体颜色设置为特定的RGB值,例如50、75、90。我已经尝试过SetConsoleTextAttribute(),但不幸的是它似乎仅限于R、G或B的0或255。这一定是可能的,因为在命令提示符属性窗口中,您可以设置特定的颜色,如下所示。

http://www.yourgamercard.net/screen/i/4a8c57.png

我已经搜索了很多,但似乎唯一的答案是SetConsoleTextAttribute()


红色、绿色和蓝色实际上在0到255范围内。任何颜色都是3个8位的组合。另请参阅-http://service.real.com/help/library/guides/realone/ProductionGuide/HTML/htmfiles/colors.htm - user405725
5
你有没有仔细阅读我的问题? - Austin Brunkhorst
当然。很显然你的问题并不清楚。你已经得到了位掩码,你也有一个函数-调用它并让你的控制台充满颜色。 - user405725
5
@Vlad,这并不简单:Win32控制台使用带有4位索引的颜色表,您不能将任何字符设置为任何RGB值。这实际上是关于Win32功能/怪癖/限制的问题,而不是关于RGB值如何工作的问题,这或许是为什么原帖作者认为您的回复没有用的原因。 - BrendanMcK
3个回答

17
你需要使用 SetConsoleScreenBufferInfoEx 来设置,参见 CONSOLE_SCREEN_BUFFER_INFOEX 结构中的 ColorTable 条目。
控制台颜色是一个两级过程:有控制台属性,其中前景和背景各有四位(红、绿、蓝和强度),似乎将颜色限制为基本的主要和次要颜色。但这些值被用作颜色表的索引,以确定实际的显示值。因此,将字符属性“颜色”位视为“逻辑红色”等,而不是物理红色。(字符属性“红色”映射到的值默认情况下实际上是RGB红色,但不必如此。)因此,你总是受限于 16 种索引颜色;但是可以通过 ColorTable 将这些值设置为任何 16 种完整的 RGB 颜色。
你在上面的对话框中看到的彩色方块条实质上就是那个颜色表,按照它们的字符属性顺序列出颜色,第一个是“逻辑黑色”,依此类推。

5
抱歉回答有点迟,以下是您所需的代码:

很抱歉晚了一些才回答,下面是您想要的代码:

CONSOLE_SCREEN_BUFFER_INFOEX info;
info.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfoEx(hConsole, &info);

info.ColorTable[0] = RGB(0,0,0);
...
info.ColorTable[3] = RGB(135, 206, 235);
...
info.ColorTable[15] = RGB (25,25,25);

SetConsoleScreenBufferInfoEx(hConsole, &info);

使用此代码,您可以将所有16个索引颜色的颜色值更改为所需的任何RGB颜色。

然后,您可以像这样打印具有所需颜色的行:

SetConsoleTextAttribute(hConsole, 3);
std::cout << "Hello World!" << std::endl;

这是我的输出结果:我的输出窗口


谢谢,这很棒。你知道如何在背景颜色上使用它吗?这似乎只适用于前景色? - David Ledger
1
@DavidLedger info.ColorTable[0] 是背景颜色的值。 - 552bb224

-2

有一种方法可以使文本完全成为RGB,但需要使用'SetPixel',如果您复制文本,则可以更改RGB值,这是我为A创建的东西,它很难做到,但我正在制作一个.h文件,以便每个人都可以使用它,给你:

void PrintA(int R, int G, int B)
{
    HWND myconsole = GetConsoleWindow();
    HDC mydc = GetDC(myconsole);
    SetPixel(mydc, i + 0, i2 + 3, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 4, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 5, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 7, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 8, RGB(R, G, B));
    SetPixel(mydc, i + 0, i2 + 9, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 2, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 3, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 4, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 5, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 7, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 8, RGB(R, G, B));
    SetPixel(mydc, i + 1, i2 + 9, RGB(R, G, B));
    SetPixel(mydc, i + 2, i2 + 1, RGB(R, G, B));
    SetPixel(mydc, i + 2, i2 + 2, RGB(R, G, B));
    SetPixel(mydc, i + 2, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 3, i2 + 1, RGB(R, G, B));
    SetPixel(mydc, i + 3, i2 + 2, RGB(R, G, B));
    SetPixel(mydc, i + 3, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 2, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 3, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 4, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 5, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 7, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 8, RGB(R, G, B));
    SetPixel(mydc, i + 4, i2 + 9, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 3, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 4, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 5, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 6, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 7, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 8, RGB(R, G, B));
    SetPixel(mydc, i + 5, i2 + 9, RGB(R, G, B));
    i += 8;

    if (i / 80 == 8)
    {
        i = 0;
        i2 += 12;
    }
}

你不能在你没有拥有的窗口上进行渲染。使用最慢的方式也无济于事。泄漏设备上下文也不行。 - IInspectable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接