// Copyright Alex Shvedov
// Modified by MercuryP with color specifications
// Use this code in any way you want
using System;
using System.Diagnostics; // for Debug
using System.Drawing; // for Color (add reference to System.Drawing.assembly)
using System.Runtime.InteropServices; // for StructLayout
class SetScreenColorsApp
{
[StructLayout(LayoutKind.Sequential)]
internal struct COORD
{
internal short X;
internal short Y;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SMALL_RECT
{
internal short Left;
internal short Top;
internal short Right;
internal short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
internal struct COLORREF
{
internal uint ColorDWORD;
internal COLORREF(Color color)
{
ColorDWORD = (uint) color.R + (((uint) color.G) << 8) + (((uint) color.B) << 16);
}
internal COLORREF(uint r, uint g, uint b)
{
ColorDWORD = r + (g << 8) + (b << 16);
}
internal Color GetColor()
{
return Color.FromArgb((int) (0x000000FFU & ColorDWORD),
(int) (0x0000FF00U & ColorDWORD) >> 8, (int) (0x00FF0000U & ColorDWORD) >> 16);
}
internal void SetColor(Color color)
{
ColorDWORD = (uint) color.R + (((uint) color.G) << 8) + (((uint) color.B) << 16);
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct CONSOLE_SCREEN_BUFFER_INFO_EX
{
internal int cbSize;
internal COORD dwSize;
internal COORD dwCursorPosition;
internal ushort wAttributes;
internal SMALL_RECT srWindow;
internal COORD dwMaximumWindowSize;
internal ushort wPopupAttributes;
internal bool bFullscreenSupported;
internal COLORREF black;
internal COLORREF darkBlue;
internal COLORREF darkGreen;
internal COLORREF darkCyan;
internal COLORREF darkRed;
internal COLORREF darkMagenta;
internal COLORREF darkYellow;
internal COLORREF gray;
internal COLORREF darkGray;
internal COLORREF blue;
internal COLORREF green;
internal COLORREF cyan;
internal COLORREF red;
internal COLORREF magenta;
internal COLORREF yellow;
internal COLORREF white;
}
const int STD_OUTPUT_HANDLE = -11; // per WinBase.h
internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); // per WinBase.h
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX csbe);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX csbe);
// Set a specific console color to an RGB color
// The default console colors used are gray (foreground) and black (background)
public static int SetColor(ConsoleColor consoleColor, Color targetColor)
{
return SetColor(consoleColor, targetColor.R, targetColor.G, targetColor.B);
}
public static int SetColor(ConsoleColor color, uint r, uint g, uint b)
{
CONSOLE_SCREEN_BUFFER_INFO_EX csbe = new CONSOLE_SCREEN_BUFFER_INFO_EX();
csbe.cbSize = (int)Marshal.SizeOf(csbe); // 96 = 0x60
IntPtr hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); // 7
if (hConsoleOutput == INVALID_HANDLE_VALUE)
{
return Marshal.GetLastWin32Error();
}
bool brc = GetConsoleScreenBufferInfoEx(hConsoleOutput, ref csbe);
if (!brc)
{
return Marshal.GetLastWin32Error();
}
switch (color)
{
case ConsoleColor.Black:
csbe.black = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkBlue:
csbe.darkBlue = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkGreen:
csbe.darkGreen = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkCyan:
csbe.darkCyan = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkRed:
csbe.darkRed = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkMagenta:
csbe.darkMagenta = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkYellow:
csbe.darkYellow = new COLORREF(r, g, b);
break;
case ConsoleColor.Gray:
csbe.gray = new COLORREF(r, g, b);
break;
case ConsoleColor.DarkGray:
csbe.darkGray = new COLORREF(r, g, b);
break;
case ConsoleColor.Blue:
csbe.blue = new COLORREF(r, g, b);
break;
case ConsoleColor.Green:
csbe.green = new COLORREF(r, g, b);
break;
case ConsoleColor.Cyan:
csbe.cyan = new COLORREF(r, g, b);
break;
case ConsoleColor.Red:
csbe.red = new COLORREF(r, g, b);
break;
case ConsoleColor.Magenta:
csbe.magenta = new COLORREF(r, g, b);
break;
case ConsoleColor.Yellow:
csbe.yellow = new COLORREF(r, g, b);
break;
case ConsoleColor.White:
csbe.white = new COLORREF(r, g, b);
break;
}
++csbe.srWindow.Bottom;
++csbe.srWindow.Right;
brc = SetConsoleScreenBufferInfoEx(hConsoleOutput, ref csbe);
if (!brc)
{
return Marshal.GetLastWin32Error();
}
return 0;
}
public static int SetScreenColors(Color foregroundColor, Color backgroundColor)
{
int irc;
irc = SetColor(ConsoleColor.Gray, foregroundColor);
if (irc != 0) return irc;
irc = SetColor(ConsoleColor.Black, backgroundColor);
if (irc != 0) return irc;
return 0;
}
}
如果你想使用橙子或者其他颜色,你可以简单的调用SetScreenColor
static void Main(string[] args)
{
Color screenTextColor = Color.Orange;
Color screenBackgroundColor = Color.Black;
int irc = SetScreenColorsApp.SetScreenColors(screenTextColor, screenBackgroundColor);
Debug.Assert(irc == 0, "SetScreenColors failed, Win32Error code = " + irc + " = 0x" + irc.ToString("x"));
Debug.WriteLine("LargestWindowHeight=" + Console.LargestWindowHeight + " LargestWindowWidth=" + Console.LargestWindowWidth);
Debug.WriteLine("BufferHeight=" + Console.BufferHeight + " WindowHeight=" + Console.WindowHeight + " BufferWidth=" + Console.BufferWidth + " WindowWidth=" + Console.WindowWidth);
//// these are relative to the buffer, not the screen:
//Debug.WriteLine("WindowTop=" + Console.WindowTop + " WindowLeft=" + Console.WindowLeft);
Debug.WriteLine("ForegroundColor=" + Console.ForegroundColor + " BackgroundColor=" + Console.BackgroundColor);
Console.WriteLine("Some text in a console window");
Console.BackgroundColor = ConsoleColor.Cyan;
Console.ForegroundColor = ConsoleColor.Yellow;
Debug.WriteLine("ForegroundColor=" + Console.ForegroundColor + " BackgroundColor=" + Console.BackgroundColor);
Console.Write("Press ENTER to exit...");
Console.ReadLine();
// Note: If you use SetScreenColors, the RGB values of gray and black are changed permanently for the console window.
// Using i.e. Console.ForegroundColor = ConsoleColor.Gray afterwards will switch the color to whatever you changed gray to
// It's best to use SetColor for the purpose of choosing the 16 colors you want the console to be able to display, then use
// Console.BackgroundColor and Console.ForegrondColor to choose among them.
}
public static class Win32
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, short attributes);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
}
public class Program
{
static void Main(string[] args)
{
foreach(var i in Enumerable.Range(0, 100)) // why "100"? it is just any number
{
Win32.SetConsoleTextAttribute(Win32.GetStdHandle(-11), (short)i);
Console.WriteLine("Hello");
}
}
}
7条答案
按热度按时间bxpogfeg1#
在http://msdn.microsoft.com/en-us/library/system.console.backgroundcolor.aspx中找到的列表
我相信这是控制台唯一支持的颜色。不允许十六进制。
编辑
从我的公共Repo中获取工作项目文件
https://bitbucket.org/benskolnick/color-console/
但是在进一步的研究中,你可以做很多工作来合并红色和黄色来获得橙子。按照这里的例子。不打算重新发布代码墙。http://support.microsoft.com/kb/319883这不会给予你访问更多的颜色,但确实会引导你朝着正确的方向前进。你需要做一些PINVOKE工作,但我很容易就能将橙色或任何其他RGB颜色放入控制台。http://pinvoke.net/default.aspx/kernel32.SetConsoleScreenBufferInfoEx
如果你想使用橙子或者其他颜色,你可以简单的调用SetScreenColor
ehxuflar2#
自Windows 10周年更新以来,控制台可以使用ANSI/VT 100颜色代码
1.您需要通过SetConsoleMode设置标志ENABLE_VIRTUAL_TERMINAL_PROCESSING(0x 4)
1.使用顺序:
"\x1b[48;5;" + s + "m"
-通过表中的索引设置背景颜色(0-255)"\x1b[38;5;" + s + "m"
-通过表中的索引设置前景色(0-255)"\x1b[48;2;" + r + ";" + g + ";" + b + "m"
-按r、g、b值设置背景"\x1b[38;2;" + r + ";" + g + ";" + b + "m"
-通过r,g,b值设置前景**重要提示:**Windows内部只有256(或88)种颜色,Windows将使用最接近表中的(r,g,b)值。
示例代码:
结果:
Read about it in MSDN: Article 'Console Virtual Terminal Sequences'
7qhs6swi3#
扩展Alexei Shcherbakov的答案Windows 10 ENABLE_VIRTUAL_TERMINAL_PROCESSING这里是一个完整的颜色代码Map,以便您在一个地方拥有所有颜色及其各自的数字:
vc6uscn94#
迟做总比不做好,但现在看来这是可能的,至少在Vista和以后的版本中是这样。
当我想这么做的时候,我遇到了Hans Passant的reply on MSDN:
我现在无法访问Vista,所以无法尝试它。但像这样的东西应该可以工作:
这将需要一点p-Invoking,但应该给予你一些东西继续下去。
pes8fvy95#
它不橙子,因为该颜色不是控制台支持的颜色之一.我的意思是,你不能得到它,即使使用windows API.如果你想验证它,看看下面的代码:
6yoyoihd6#
进一步证明这不起作用(使用Benjamin链接中的方法):
这种方法不允许你添加任何无法通过ConsoleColor到达的东西。这是一个真实的的耻辱,因为我也很想添加橙子到我的应用程序。如果有人找到了一种方法,我会非常感兴趣。
jgwigjjp7#
有点晚了,我知道。但是在C#控制台中实现通常不可用的颜色的一种方法是在注册表中更改颜色的ColorCode。但是要注意,这可能是最不可接受的方法。只需打开regedit(Win + R,然后键入“regedit”),转到HKEY_CURRENT_USER,打开“控制台”键(此时,您应该导出“Console”键以便稍后恢复它)。在那里,您将看到从ColorTable00到ColoTable15的值列表。如果您更改,比方说,ColorTable10从0x0000ff00到0x0000a5ff(或65280到42495)当您使用ConsoleColor时,您将拥有橙子。重新启动后在Console中显示绿色。您也可以通过代码更改此值
当然,这适用于所有其他ColorTable值和Colorcodes,但它只针对您PC上的用户进行更改。