Jimmy
Jimmy

Reputation: 91482

Advanced Console IO in .NET

What is the best way to write data to the text console at arbitrary locations on the screen and with custom fore/background colors?

Upvotes: 19

Views: 8997

Answers (4)

Magnus Lindhe
Magnus Lindhe

Reputation: 7327

There are a couple of libraries that can be helpful when writing TUI based applications in C#:

  • Gui.cs is a Terminal UI toolkit for .NET by Miguel de Icaza. This is a simple UI toolkit for .NET, .NET Core and Mono and works on both Windows and Linux/Unix.
  • MonoCurses is an MIT-X11 licensed binding of curses, and it includes the minimalistic gui.cs GUI toolkit for creating console-based applications.
  • ConsoleGUI is a simple layout-driven library for creating console-based GUI applications. It provides most essential layout management utilities as well as a set of basic controls.
  • CursesSharp is a C# wrapper for curses library.

Upvotes: 8

Igor Kostomin
Igor Kostomin

Reputation: 79

Most effective function is WriteConsoleOutput. It is native win32 API, but can be used in .NET application using p/invoke:

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

Where CHAR_INFO is a structure:

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

Attr structure:

/// <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 and 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;
    }
}

Upvotes: 2

Werg38
Werg38

Reputation: 1130

This posting shows how to use Console class methods to create a progress bar on the console - it might be a good example to refer to....

Upvotes: 4

C. Dragon 76
C. Dragon 76

Reputation: 10072

Console.SetCursorPosition, Console.BackgroundColor, Console.ForegroundColor, and Console.ResetColor.

Note these were added to the .NET Framework in version 2.0. Prior to that you would have needed PInvoke.

Upvotes: 27

Related Questions