Welcome to AddressOf.com Sign in | Join | Help

Color your console output using VB.NET!

By Cory Smith

Note: This sample has been replaced by the “Control Your Console“ ConsoleEx sample available from the Samples listing.  In addition to being able to specify the color, you can control cursor position, window title, determine size of the console and much more.

Download source code - 2.28kb

Introduction

Back in the days before Windows (yes, even Windows 3.x) we used to have applications that took advantage of the DOS prompt's ability to change the foreground and background colors to present data in a more meaningful manner.  As we've move foreward with a Windows interface, developers creating console applications have all but forgotten that they too have this ability.  Sure, most of the time, these applications are for testing purposes, but it would still be nice to have the output presented in a manner that allows the user to quickly identify important portions of the data that is being presented.  For example, you could have a console application that shows you the output of some task; presenting you with successful, questionable, and failed/error events.  Each of these could be marked using green, yellow, and red foreground colors to allow the user to quickly identify one type of event over the others based on color alone.

Now, for the problem.  .NET console applications do not give you the ability to modify the foreground and background colors of what you output to the screen.  However, since .NET console application are true Windows console applications, we can leverage a few Windows API's to assist us with this problem.

We we're going to do is wrap up the necessary API calls into a re-usable component class.  We're going to expand upon the flag values by creating all of the variations of the colors; instead of relying on Or'ing all of the values to create the various combinations.  This will give us more of a .NET feel.  In the end, this re-usable component will have three overloaded shared methods that allows us to modify the output colors.  We will also mark this class so that we can't create an instance of the class; only allowing for the shared access methods.

ConsoleColor.vb

Option

Explicit On
Option Strict On

Imports
System.Runtime.InteropServices
Imports Win32.Kernel32.ConsoleColor

Namespace Win32.Kernel32

  Class ConsoleColor

     
Public Enum ForegroundColors
        Black = 0
        Blue = 1
        Green = 2
        Cyan = Blue
Or Green
        Red = 4
        Magenta = Blue
Or Red
        Yellow = Green
Or Red
        White = Blue
Or Green Or Red
        Gray = 8
        LightBlue = Gray
Or Blue
        LightGreen = Gray
Or Green
        LightCyan = Gray
Or Cyan
        LightRed = Gray
Or Red
        LightMagenta = Gray
Or Magenta
        LightYellow = Gray
Or Yellow
        BrightWhite = Gray
Or White
      End Enum

     

Public Enum BackgroundColors
        Black = 0
        Blue = 16
        Green = 32
        Cyan = Blue
Or Green
        Red = 64
        Magenta = Blue
Or Red
        Yellow = Green
Or Red
        White = Blue
Or Green Or Red
        Gray = 128
        LightBlue = Gray
Or Blue
        LightGreen = Gray
Or Green
        LightCyan = Gray
Or Cyan
        LightRed = Gray
Or Red
        LightMagenta = Gray
Or Magenta
        LightYellow = Gray
Or Yellow
        BrightWhite = Gray
Or White
    End Enum

    Public Enum Attributes
        None = &H0
        GridHorizontal = &H400
        GridLVertical = &H800
        GridRVertical = &H1000
        ReverseVideo = &H4000
        Underscore = &H8000
    End Enum
 
   
Private Const STD_OUTPUT_HANDLE As Integer = -11
   
Private Shared InvalidHandleValue As New IntPtr(-1)
 
   
Private Sub New()
     
' This class can not be instantiated.
   
End Sub
 
   
' Our wrapper implementations.
   
Public Overloads Shared Sub SetConsoleColor(ByVal foreground As ForegroundColors)
      SetConsoleColor(foreground, BackgroundColors.Black, Attributes.None)
   
End Sub
 
   
Public Overloads Shared Sub SetConsoleColor(ByVal foreground As ForegroundColors, _
                                                                                       
ByVal background As BackgroundColors)
      SetConsoleColor(foreground, background, Attributes.None)
   
End Sub
 
   
Public Overloads Shared Sub SetConsoleColor(ByVal foreground As ForegroundColors, _
                                                                                        
ByVal background As BackgroundColors, _
                                                                                       
ByVal attribute As Attributes)
     
Dim handle As IntPtr = GetStdHandle(STD_OUTPUT_HANDLE)
     
If handle.Equals(InvalidHandleValue) Then
       
Throw New System.ComponentModel.Win32Exception()
     
End If
      ' We have to convert the integer flag values into a Unsigned Short (UInt16) to pass to the
      ' SetConsoleTextAttribute API call.
     
Dim value As UInt16 = System.Convert.ToUInt16(foreground Or background Or attribute)
     
If Not SetConsoleTextAttribute(handle, value) Then
       
Throw New System.ComponentModel.Win32Exception()
     
End If
   
End Sub

    ' DLLImport's (Win32 functions)
   
True)> _
   
Private Shared Function GetStdHandle(ByVal stdHandle As Integer) As IntPtr
   
End Function

   
True)> _
   
Private Shared Function SetConsoleTextAttribute(ByVal consoleOutput As IntPtr, _
                                                                                             _
                                                                                            
ByVal Attributes As UInt16) As Boolean
   
End Function

  End Class

End

Namespace

Now that we have our re-usable class, let's create a test application to try out our new capabilities we've added to the console.  NOTE: I've added the Attributes portion for completeness; however, it doesn't appear to work using Windows XP.

ConsoleColorTest.vb

Option

Explicit On
Option Strict On

Imports Win32.Kernel32.ConsoleColor

Module ConsoleColorTest
 
Sub Main()

    
Dim bgcolor As BackgroundColors
   
Dim fgcolor As ForegroundColors

   
' Show every variation of the color combinations.
   
For Each bgcolor In [Enum].GetValues(GetType(BackgroundColors))
      For Each fgcolor In [Enum].GetValues(GetType(ForegroundColors))
        SetConsoleColor(fgcolor, bgcolor)
        Console.WriteLine(bgcolor.ToString.PadRight(15) & fgcolor.ToString.PadRight(64))
     
Next
   
Next

    
' Set the color back to the default.
    
SetConsoleColor(ForegroundColors.White, BackgroundColors.Black)

    
' Wait for input, so we can view the results.
   
Console.ReadLine()
  
End Sub
End Module

This demo is pretty straight forward.  It simply loops through all of the foreground and background values to display every combination of the values.  As you can see, it's now very simple to add the capability to modify the foreground and background color of your console applications output.

I have to point out one of the cool parts of this sample.  You can iterate through an enumeration pretty much like any other "collection".  You have to use the Enum.GetValues method to do this.  Notice, since Enum is a reserved word in VB, you have to place the square brackets around it.

Conclusion

There is a lot more that you can do with the console output.  This includes moving the cursor position, set font size, and change the window title.   The code provided will give you a head start on implementing any additional functionality that the Platform SDK offers concerning console applications.  As you can see, VB.NET's not having unsigned values does not hinder us from implementing this functionality.  The System.Convert class comes in very handy, as does the MarshalAs attribute for these sticky situations.

[UPDATE] If there is any interest, I've expanded on this quite a bit.  The version that I'm working on allows you to clear the screen, move the cursor around, etc. allowing you work with a command prompt similar to back in the good ol' QB4.5 days ;-)  If enough comments are left, I'll consider created a part two to this article... so start commenting ;-)

Resources

SetConsoleTextAttribute (Platform SDK / MSDN)
Writing colored text to the console (C#) by Shawn A. Van Ness
Putting colour/color to work on the console by Philip Fitzsimons (C#)

Published Thursday, October 30, 2003 10:37 PM by CorySmith
Filed under: ,

Comments

# Code Samples

Saturday, December 27, 2003 1:43 AM by AddressOf.com

# re: Color your console output using VB.NET!

Thursday, May 27, 2004 1:03 PM by Anders Nissen
Hmm... I wonder why anyone else haven't made a comment. But I guess I'll have the honour of being the first :)
Your article one coloring the console is simple and to the point, yet it's nicely reuseable and extremely handy when developing console applications! I liked it!

I've been researching a bit about how to use fore- and backcoloring in the console, and found the "SetConsoleTextAttribute"-API cabable of doing it. But this functionality as apparently been removed from VB .NET, and I was very happy to find that the otherwise extint kernel32.dll-functions could be integrated into VB .NET this easy.

In your update, probably made quite a long time ago, you mention that you've been working on a extended version of your article. Well, more flexability and control is always a good thing, and I really hope that you will make your new version into an article... despite the lacking comments :)

Good job.

# re: Color your console output using VB.NET!

Wednesday, June 23, 2004 12:07 AM by Dan
It's strange that VB.NET can't do something that you could do in the original BASIC. Thanks for the article, helped tons.

# re: Color your console output using VB.NET!

Sunday, July 4, 2004 6:10 AM by Cory Smith
Well, keep in mind that most people have moved away from doing any 'DOS' type applications. You really don't see many console applications displaying things in color or doing any cursor manipulations (ala ANSI Graphics). I think it's more of a supply and demand sort of thing... and for what it's worth... VB8 *will* included most (if not all) of these features directly accessible from the Console portion .NET CLR. :-D

# re: Color your console output using VB.NET!

Thursday, February 3, 2005 9:01 PM by Corey
this is quite helpful as i have been looking for a console coloring for quite some time.
thanx for it.

# re: Color your console output using VB.NET!

Sunday, February 6, 2005 12:17 AM by Rob H
This code is very nicely done. For future readers, it is worth noting that the > in the DLL imports hides the actual syntax. You can find the DLL import under http://www.mentalis.org/forum/thread.qpx/111

# re: Color your console output using VB.NET!

Thursday, April 14, 2005 10:09 PM by Denny Peltz
Is there a way to iterate an enum in VB6?

# re: Color your console output using VB.NET!

Tuesday, July 12, 2005 5:46 PM by Eric
Rumor has it that the .NET 2.0 will support changing colors in the console. Both foreground and background, as well as some other features.

But Thanx for the code sample... I learned a bit about wrapping API's, and I am sure I can use that elsewhere... :)
Anonymous comments are disabled