P
Publicjoe
I am working on a little app which uses colour in the console window. I have
created a class to extend the console functionality but the ClearScreen
method does not work correctly. I am enclosing a complete project
to show what happens. If anybody has an idea of how to fix
this, please let me know.
Yes I am aware that this is all in .Net 2.
Thanks in advance.
Publicjoe
----- Main.cs -----
using System;
using Publicjoe.Console;
namespace ColourTest
{
class MainClass
{
public static void Main(string[] args)
{
ConsoleExt TextChange = new ConsoleExt();
Console.WriteLine("Original Colors");
Console.WriteLine("Press Enter to Begin");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Green +
(int)ConsoleExt.Foreground.Intensity);
Console.WriteLine("THIS TEXT IS GREEN");
Console.WriteLine("Press Enter to change colors again");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Red +
(int)ConsoleExt.Foreground.Blue +
(int)ConsoleExt.Foreground.Intensity);
Console.WriteLine("NOW THE TEXT IS PURPLE");
Console.WriteLine("Press Enter to change colors again");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Blue +
(int)ConsoleExt.Foreground.Intensity +
(int)ConsoleExt.Background.Green +
(int)ConsoleExt.Background.Intensity);
Console.WriteLine("NOW THE TEXT IS BLUE AND BACKGROUND OF IT IS
GREEN");
Console.WriteLine("Press Enter change everything back to normal");
Console.ReadLine();
TextChange.ResetColor();
TextChange.ClearScreen();
Console.WriteLine("Back to Original Colors");
Console.WriteLine("Press Enter to Terminate");
Console.ReadLine();
}
}
}
----- End -----
----- ConsoleExt.cs ----
using System;
using System.Runtime.InteropServices;
namespace Publicjoe.Console
{
public class ConsoleExt
{
private const int STD_INPUT_HANDLE = -10;
private const int STD_OUTPUT_HANDLE = -11;
private const int STD_ERROR_HANDLE = -12;
private const ushort KEY_EVENT = 1;
private const ushort MOUSE_EVENT = 2;
private const ushort WINDOW_BUFFER_SIZE_EVENT = 4;
private const ushort MENU_EVENT = 8;
private const ushort FOCUS_EVENT = 16;
private const byte EMPTY = 32;
private IntPtr hConsoleHandle;
private COORD ConsoleOutputLocation;
private CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
private int OriginalColors;
[StructLayout(LayoutKind.Sequential)]
struct COORD
{
public short x;
public short y;
}
[StructLayout(LayoutKind.Sequential)]
struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public int wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
}
// Key press event information
struct KEY_EVENT_RECORD
{
public bool bKeyDown;
public ushort wRepeatCount;
public ushort wVirtualKeyCode;
public ushort wVirtualScanCode;
public byte AsciiChar; // we'll only process ASCII
public uint dwControlKeyState;
}
// Information about the console input
struct INPUT_RECORD
{
public ushort EventType;
public KEY_EVENT_RECORD KeyEvent;
};
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
private static extern bool FillConsoleOutputCharacter(IntPtr
hConsoleHandle, byte cCharacter, int nLength, COORD dwWriteCoord, ref int
lpNumberOfCharsWritten);
[DllImport("kernel32.dll")]
private static extern bool GetConsoleScreenBufferInfo(IntPtr
hConsoleHandle, ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleCursorPosition(IntPtr
hConsoleOutput, COORD dwCursorPosition);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint
mode);
[DllImport("kernel32.dll")]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out
uint mode);
[DllImport("kernel32.dll")]
private static extern bool ReadConsoleInputA(IntPtr hConsoleHandle, out
INPUT_RECORD rec, uint len, out uint c);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleTextAttribute(IntPtr
hConsoleOutput, int Attributes );
public enum Foreground
{
Blue = 0x00000001,
Green = 0x00000002,
Red = 0x00000004,
Intensity = 0x00000008
}
public enum Background
{
Blue = 0x00000010,
Green = 0x00000020,
Red = 0x00000040,
Intensity = 0x00000080
}
public ConsoleExt()
{
ConsoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();
ConsoleOutputLocation = new COORD();
hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleHandle, ref ConsoleInfo);
OriginalColors = ConsoleInfo.wAttributes;
}
/// <summary>
/// Clear the Console window
/// </summary>
public void ClearScreen()
{
int hWrittenChars = 0;
ConsoleOutputLocation.x = 0;
ConsoleOutputLocation.y = 0;
FillConsoleOutputCharacter(hConsoleHandle, EMPTY, ConsoleInfo.dwSize.x
* ConsoleInfo.dwSize.y, ConsoleOutputLocation, ref hWrittenChars);
SetConsoleCursorPosition(hConsoleHandle, ConsoleOutputLocation);
}
/// <summary>
/// Get a single character from the console
/// </summary>
/// <returns>Key that has been pressed</returns>
public int ReadKey()
{
int ch = 0;
IntPtr stdin = GetStdHandle(STD_INPUT_HANDLE);
uint oldstate;
// Save the existing mode
GetConsoleMode(stdin, out oldstate);
// Set the mode to character input
SetConsoleMode(stdin, 0);
// Read the console input until we get a single character
while(true)
{
INPUT_RECORD rec;
rec.EventType = 0;
rec.KeyEvent.bKeyDown = false;
rec.KeyEvent.wRepeatCount = rec.KeyEvent.wVirtualKeyCode =
rec.KeyEvent.wVirtualScanCode = 0;
rec.KeyEvent.AsciiChar = 0;
rec.KeyEvent.dwControlKeyState = 0;
uint NumRead;
// Read the next console event
if (!ReadConsoleInputA(stdin, out rec, 1, out NumRead))
{
// A problem has occurred, treat it as EOF
ch = -1;
break;
}
// Check that a button was pressed
if (((rec.EventType & KEY_EVENT) > 0) && rec.KeyEvent.bKeyDown)
{
if ((ch = rec.KeyEvent.AsciiChar) > 0)
{
break;
}
}
}
// Restore the old console mode
SetConsoleMode(stdin, oldstate);
// Return the character
return ch;
}
/// <summary>
/// Set the text color
/// </summary>
/// <param name="color"></param>
public void TextColor(int color)
{
SetConsoleTextAttribute(hConsoleHandle, color);
}
/// <summary>
/// Reset the text color back to normal
/// </summary>
public void ResetColor()
{
SetConsoleTextAttribute(hConsoleHandle, OriginalColors);
}
}
}
----- End -----
created a class to extend the console functionality but the ClearScreen
method does not work correctly. I am enclosing a complete project
to show what happens. If anybody has an idea of how to fix
this, please let me know.
Yes I am aware that this is all in .Net 2.
Thanks in advance.
Publicjoe
----- Main.cs -----
using System;
using Publicjoe.Console;
namespace ColourTest
{
class MainClass
{
public static void Main(string[] args)
{
ConsoleExt TextChange = new ConsoleExt();
Console.WriteLine("Original Colors");
Console.WriteLine("Press Enter to Begin");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Green +
(int)ConsoleExt.Foreground.Intensity);
Console.WriteLine("THIS TEXT IS GREEN");
Console.WriteLine("Press Enter to change colors again");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Red +
(int)ConsoleExt.Foreground.Blue +
(int)ConsoleExt.Foreground.Intensity);
Console.WriteLine("NOW THE TEXT IS PURPLE");
Console.WriteLine("Press Enter to change colors again");
Console.ReadLine();
TextChange.TextColor((int)ConsoleExt.Foreground.Blue +
(int)ConsoleExt.Foreground.Intensity +
(int)ConsoleExt.Background.Green +
(int)ConsoleExt.Background.Intensity);
Console.WriteLine("NOW THE TEXT IS BLUE AND BACKGROUND OF IT IS
GREEN");
Console.WriteLine("Press Enter change everything back to normal");
Console.ReadLine();
TextChange.ResetColor();
TextChange.ClearScreen();
Console.WriteLine("Back to Original Colors");
Console.WriteLine("Press Enter to Terminate");
Console.ReadLine();
}
}
}
----- End -----
----- ConsoleExt.cs ----
using System;
using System.Runtime.InteropServices;
namespace Publicjoe.Console
{
public class ConsoleExt
{
private const int STD_INPUT_HANDLE = -10;
private const int STD_OUTPUT_HANDLE = -11;
private const int STD_ERROR_HANDLE = -12;
private const ushort KEY_EVENT = 1;
private const ushort MOUSE_EVENT = 2;
private const ushort WINDOW_BUFFER_SIZE_EVENT = 4;
private const ushort MENU_EVENT = 8;
private const ushort FOCUS_EVENT = 16;
private const byte EMPTY = 32;
private IntPtr hConsoleHandle;
private COORD ConsoleOutputLocation;
private CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
private int OriginalColors;
[StructLayout(LayoutKind.Sequential)]
struct COORD
{
public short x;
public short y;
}
[StructLayout(LayoutKind.Sequential)]
struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public int wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
}
// Key press event information
struct KEY_EVENT_RECORD
{
public bool bKeyDown;
public ushort wRepeatCount;
public ushort wVirtualKeyCode;
public ushort wVirtualScanCode;
public byte AsciiChar; // we'll only process ASCII
public uint dwControlKeyState;
}
// Information about the console input
struct INPUT_RECORD
{
public ushort EventType;
public KEY_EVENT_RECORD KeyEvent;
};
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
private static extern bool FillConsoleOutputCharacter(IntPtr
hConsoleHandle, byte cCharacter, int nLength, COORD dwWriteCoord, ref int
lpNumberOfCharsWritten);
[DllImport("kernel32.dll")]
private static extern bool GetConsoleScreenBufferInfo(IntPtr
hConsoleHandle, ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleCursorPosition(IntPtr
hConsoleOutput, COORD dwCursorPosition);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint
mode);
[DllImport("kernel32.dll")]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out
uint mode);
[DllImport("kernel32.dll")]
private static extern bool ReadConsoleInputA(IntPtr hConsoleHandle, out
INPUT_RECORD rec, uint len, out uint c);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleTextAttribute(IntPtr
hConsoleOutput, int Attributes );
public enum Foreground
{
Blue = 0x00000001,
Green = 0x00000002,
Red = 0x00000004,
Intensity = 0x00000008
}
public enum Background
{
Blue = 0x00000010,
Green = 0x00000020,
Red = 0x00000040,
Intensity = 0x00000080
}
public ConsoleExt()
{
ConsoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();
ConsoleOutputLocation = new COORD();
hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleHandle, ref ConsoleInfo);
OriginalColors = ConsoleInfo.wAttributes;
}
/// <summary>
/// Clear the Console window
/// </summary>
public void ClearScreen()
{
int hWrittenChars = 0;
ConsoleOutputLocation.x = 0;
ConsoleOutputLocation.y = 0;
FillConsoleOutputCharacter(hConsoleHandle, EMPTY, ConsoleInfo.dwSize.x
* ConsoleInfo.dwSize.y, ConsoleOutputLocation, ref hWrittenChars);
SetConsoleCursorPosition(hConsoleHandle, ConsoleOutputLocation);
}
/// <summary>
/// Get a single character from the console
/// </summary>
/// <returns>Key that has been pressed</returns>
public int ReadKey()
{
int ch = 0;
IntPtr stdin = GetStdHandle(STD_INPUT_HANDLE);
uint oldstate;
// Save the existing mode
GetConsoleMode(stdin, out oldstate);
// Set the mode to character input
SetConsoleMode(stdin, 0);
// Read the console input until we get a single character
while(true)
{
INPUT_RECORD rec;
rec.EventType = 0;
rec.KeyEvent.bKeyDown = false;
rec.KeyEvent.wRepeatCount = rec.KeyEvent.wVirtualKeyCode =
rec.KeyEvent.wVirtualScanCode = 0;
rec.KeyEvent.AsciiChar = 0;
rec.KeyEvent.dwControlKeyState = 0;
uint NumRead;
// Read the next console event
if (!ReadConsoleInputA(stdin, out rec, 1, out NumRead))
{
// A problem has occurred, treat it as EOF
ch = -1;
break;
}
// Check that a button was pressed
if (((rec.EventType & KEY_EVENT) > 0) && rec.KeyEvent.bKeyDown)
{
if ((ch = rec.KeyEvent.AsciiChar) > 0)
{
break;
}
}
}
// Restore the old console mode
SetConsoleMode(stdin, oldstate);
// Return the character
return ch;
}
/// <summary>
/// Set the text color
/// </summary>
/// <param name="color"></param>
public void TextColor(int color)
{
SetConsoleTextAttribute(hConsoleHandle, color);
}
/// <summary>
/// Reset the text color back to normal
/// </summary>
public void ResetColor()
{
SetConsoleTextAttribute(hConsoleHandle, OriginalColors);
}
}
}
----- End -----