【发布时间】:2010-09-16 23:49:05
【问题描述】:
在屏幕上的任意位置使用自定义前景色/背景色将数据写入文本控制台的最佳方式是什么?
【问题讨论】:
在屏幕上的任意位置使用自定义前景色/背景色将数据写入文本控制台的最佳方式是什么?
【问题讨论】:
Console.SetCursorPosition、Console.BackgroundColor、Console.ForegroundColor 和 Console.ResetColor。
请注意,这些是在 2.0 版中添加到 .NET Framework 中的。在此之前,您需要 PInvoke。
【讨论】:
在用 C# 编写基于 TUI 的应用程序时,有几个库会很有帮助:
【讨论】:
This posting 展示了如何使用 Console 类方法在控制台上创建进度条 - 这可能是一个很好的示例,可以参考......
【讨论】:
最有效的函数是WriteConsoleOutput。它是原生的 win32 API,但可以使用 p/invoke 在 .NET 应用程序中使用:
[DllImport("kernel32.dll", SetLastError = true, EntryPoint = "WriteConsoleOutputW")]
public static extern bool WriteConsoleOutput(IntPtr hConsoleOutput, CHAR_INFO[,] lpBuffer, COORD dwBufferSize,
COORD dwBufferCoord, ref SMALL_RECT lpWriteRegion);
CHAR_INFO 是一个结构:
/// <summary>
/// CharSet.Unicode is required for proper marshaling.
/// </summary>
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct CHAR_INFO
{
[FieldOffset(0)]
public char UnicodeChar;
[FieldOffset(0)]
public char AsciiChar;
[FieldOffset(2)] //2 bytes seems to work properly
public Attr Attributes;
public override string ToString() {
return string.Format("CHAR_INFO : '{0}' ({1})", AsciiChar, Attributes);
}
}
属性结构:
/// <summary>
/// CHAR_ATTRIBUTES native structure.
/// </summary>
[Flags]
public enum Attr : ushort {
NO_ATTRIBUTES = 0x0000,
/// <summary>
/// Text color contains blue.
/// </summary>
FOREGROUND_BLUE = 0x0001,
/// <summary>
/// Text color contains green.
/// </summary>
FOREGROUND_GREEN = 0x0002,
/// <summary>
/// Text color contains red.
/// </summary>
FOREGROUND_RED = 0x0004,
/// <summary>
/// Text color is intensified.
/// </summary>
FOREGROUND_INTENSITY = 0x0008,
/// <summary>
/// Background color contains blue.
/// </summary>
BACKGROUND_BLUE = 0x0010,
/// <summary>
/// Background color contains green.
/// </summary>
BACKGROUND_GREEN = 0x0020,
/// <summary>
/// Background color contains red.
/// </summary>
BACKGROUND_RED = 0x0040,
/// <summary>
/// Background color is intensified.
/// </summary>
BACKGROUND_INTENSITY = 0x0080,
/// <summary>
/// Leading byte.
/// </summary>
COMMON_LVB_LEADING_BYTE = 0x0100,
/// <summary>
/// Trailing byte.
/// </summary>
COMMON_LVB_TRAILING_BYTE = 0x0200,
/// <summary>
/// Top horizontal
/// </summary>
COMMON_LVB_GRID_HORIZONTAL = 0x0400,
/// <summary>
/// Left vertical.
/// </summary>
COMMON_LVB_GRID_LVERTICAL = 0x0800,
/// <summary>
/// Right vertical.
/// </summary>
COMMON_LVB_GRID_RVERTICAL = 0x1000,
/// <summary>
/// Reverse foreground and background attribute.
/// </summary>
COMMON_LVB_REVERSE_VIDEO = 0x4000,
/// <summary>
/// Underscore.
/// </summary>
COMMON_LVB_UNDERSCORE = 0x8000
}
COORD 和 SMALL_RECT:
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
public COORD(short X, short Y)
{
this.X = X;
this.Y = Y;
}
};
[StructLayout(LayoutKind.Sequential)]
public struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
public SMALL_RECT(short left, short top, short right, short bottom) {
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
}
【讨论】: