Jim Lawless' Blog


Setting Windows Console Text Colors in C

Originally published on: Sat, 20 Mar 2010 23:41:26 +0000

Please note! If you're having difficulties compiling the C source code presented below, please see my post: Compiling C from the Command Line with Pelles C

A number of visitors to my blog end up here via a search for information on changing the text color in a C program. Unfortunately, the only post I have on the subject pertains to changing the output text color for the Commodore 64. I doubt that the technique I used there is of any kind of importance to these searchers.

In a Win32 environment, the console mode text background color and foreground color can be changed by a single Windows API function. The SetConsoleTextAttribute() function was first exposed via kernel32.dll in Windows 2000.

This API call accepts a console output handle as the first parameter. The second parameter is the attribute used to control both the background color and foreground color. The console text color palette is divided into sixteen different values. Each color value can be represented by one hexadecimal digit:

When specifying a digit to the SetConsoleTextAttribute() function, the background color is specified in the first digit and the foreground color is specified in the second. Passing the value 1F to SetConsoleTextAttribute() would yield a blue background with bright white text.

Note that you can already experiment with these color combinations from the command prompt by using the standard color command:

color 1F

By typing the above command at a command prompt, the entire screen should now show bright white on blue. To go back to the default color scheme simply type:

color

Do not supply any parameters to the above.

Unfortunately, my C compiler is a bit old, so I did not have the definitions nor link-time information to allow me to easily compile a program. As such, I had to explicitly attempt to load the function from kernel32.dll as a pointer. I then had invoked the function using the asterisk as a dereference operator via my function-pointer named doSetConsoleTextAttribute()

I wrote a demonstration program that will loop through all 256 combinations of foreground and background colors and will display them in the console window. You may have to scroll up in your console window to see all of the output.

colordemo.c


// Win32 console text-color demo
//
// License: MIT / X11
// Copyright (c) 2009 by James K. Lawless
// jimbo@radiks.net http://www.radiks.net/~jimbo
// http://www.mailsend-online.com
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include <windows.h>
#include <stdio.h>

   // get the pointer to a function from kernel32.dll
void *getConsoleFunction(char *name);

   // pointer to the SetConsoleTextAttribute() winapi function
BOOL (WINAPI *doSetConsoleTextAttribute)(HANDLE hConsoleOutput, WORD attr);

int main(int argc,char **argv) {

   HANDLE hCon;
   int i,j;
   
   hCon=GetStdHandle(STD_OUTPUT_HANDLE);
         
   doSetConsoleTextAttribute=getConsoleFunction("SetConsoleTextAttribute");

   if(doSetConsoleTextAttribute==NULL) {
      fprintf(stderr,"Sorry! colordemo is incompatible with this version of Windows.");
      return 1;
   }
   
      // Generate 64 lines of various color combinations
   for(i=0;i<16;i++) {
      for(j=0;j<16;j++) {
         (*doSetConsoleTextAttribute)(hCon,(i*16)+j);
         printf("[i is %2x j is %2x]",i,j);
      }
   }
   
      // set the color scheme to white on black
   (*doSetConsoleTextAttribute)(hCon,7);

   return 0;
}

void *getConsoleFunction(char *name) {
   static HMODULE kernel32=(HMODULE)0xffffffff;
   if(kernel32==0)
      return NULL;
   if(kernel32==(HMODULE)0xffffffff) {
      kernel32=LoadLibrary("kernel32.dll");
      if(kernel32==0)
         return 0;
   }
   return GetProcAddress(kernel32,name);
}

In addition to this demo, I've written a command-line utility called chgcolor. The post describing how to use this utility in batch files ( with C source code ) can be found at http://www.mailsend-online.com/blog?p=77. A link to the EXE file can also be found there.

The source code and executable file for colordemo can be downloaded from a single archive at: http://www.mailsend-online.com/wp/colordemo.zip

Unless otherwise noted, all code and text entries are Copyright 2010 by James K. Lawless



Views expressed in this blog are those of the author and do not necessary reflect those of the author's employer. Views expressed in the comments are those of the responding individual.

stumbleupon Save to StumbleUpon
digg Digg it
reddit Save to Reddit
facebook Share on Facebook
twitter Share on Twitter
aolfav More bookmarks


Previous post: Setting Text Color in a Batch File
Next post:Choose your own Adventure with Sinatra


About Jim ...


Follow me on Twitter

http://twitter.com/lawlessGuy


My GitHub Repository

https://github.com/jimlawless


Recent Posts

Compiling C from the Command Line with Pelles C

A Forthcoming Marvel Movie Villain

Uninstalling Problematic Windows Software

Don't be Hatin'

A JavaScript REPL for Android Devices

MailSend is Free

My Blog Engine

The October 10th Bug


Random Posts

CP/M Days

Charging by the Byte

A Quine in C

Speeding up JRuby with NailGun

A TCP Command Line Interface in Rhino JavaScript

A Simple ROT13 Macro

Java in a Windows EXE with launch4j

Spellbound by Web Programming

Preserving my Favorite HN Links

Auto Save Clipboard Images Redux


Full List of Posts

http://www.mailsend-online.com/bloglist.htm


Recent Posts from my Other Blog / GitHub

JavaScript Libraries in Yosemite

Command Line JavaScript in Yosemite

Text to Speech, Yosemite, and JavaScript

A Simple (but useful) TCP Client Written in Go

Yet Another Seven Languages in Seven Weeks

Happy 50th Birthday, BASIC

Extending Commodore 64 BASIC

Hide the HTTP-Referer using HTML and JS

RSS Feed Processing in Python

A Chromecast Slideshow using Python

A Simple Perl REPL

Linux Mint on a Toshiba Netbook

Find and View All Images on a HD with Perl

Pretty-Printing an s-expression in Go

My Personal Text to HTML Utility

1985 Computing : Atari and Commodore

My Mac has Mono

Yet Another Config File Reader for Go (Golang)

Filling a Slice Using Command-line Flags in Go (Golang)

An RPN Interpreter in Go (Golang)

Simulating Try-Catch in Go (Golang)

Sending GMail with Go (Golang)

Variant Types in Golang

My First C64 Interrupt Program

The Triangles Puzzle

Happy 25th, Perl !

My Favorite BASIC One-Liner

Playing with OS/X Text to Speech

The Villain at the end of Marvel's Avengers Move is...

Chicken! Fight like a Robot!

Processing GMail items with Ruby

The Squares Puzzle

Happy 30th Birthday, Commodore 64

Scripting Safari

MailWrench CSharp Command Line Mailer for Windows is now Free Software

Welcome Back, M.U.L.E. !

Rainy Day Fun with the HTML DOM

Building a World War II Foxhole Radio

Prototerp Unleashing a JavaScript REPL via the Mobile Browser

Steal This Bookmarklet

Happy Birthday, Miles