19

在屏幕上的任意位置并使用自定义前/背景颜色将数据写入文本控制台的最佳方法是什么?

4

4 回答 4

26

Console.SetCursorPosition、Console.BackgroundColor、Console.ForegroundColor 和 Console.ResetColor。

请注意,这些是在 2.0 版中添加到 .NET Framework 中的。在此之前,您需要 PInvoke。

于 2008-10-13T22:58:27.780 回答
8

在用 C#编写基于TUI的应用程序时,有几个库会很有帮助:

  • Gui.cs是 Miguel de Icaza 的 .NET 终端 UI 工具包。这是一个用于 .NET、.NET Core 和 Mono 的简单 UI 工具包,适用于 Windows 和 Linux/Unix。
  • MonoCurses是一个 MIT-X11 许可的 curses 绑定,它包括用于创建基于控制台的应用程序的简约 gui.cs GUI 工具包。
  • ConsoleGUI是一个简单的布局驱动库,用于创建基于控制台的 GUI 应用程序。它提供了最重要的布局管理实用程序以及一组基本控件。
  • CursesSharp是 curses 库的 C# 包装器。
于 2008-10-13T23:04:28.937 回答
4

这篇文章展示了如何使用控制台类方法在控制台上创建一个进度条——它可能是一个很好的例子,可以参考......

于 2008-10-13T23:39:07.477 回答
2

最有效的功能是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;
    }
}
于 2014-02-27T10:07:13.670 回答