The other day I created a Console application and changed some colors and sizes. Then I needed to change the font (programmatically). I looked at the System.Console class – nothing. Maybe they just forgot to wrap it up, I thought, and turned to the Win32 API functions for the Console. Guess what? Nothing. Well, almost nothing. There’s a new function (starting with Vista) called SetCurrentConsoleFontEx, but it’s almost useless. It requires a console font index (which is supposed to be from a console font table, which no documented API reveals), and it doesn’t seem to work quite as expected. The font size is given as a COORD structure (in “logical” units, where “logical” is not explained), and even then, only certain sizes actually work, with no indication why).
All this can be done pretty easily through a “shortcut” to the console app (IShellLink), but I needed something more dynamic, to be available at runtime.
This felt really wrong. It seems that some functions are missing. A quick google and some depends.exe reveals that there are actually a few functions that can help in kernel32.dll, namely SetConsoleFont, GetConsoleFontInfo and GetNumberOfConsoleFonts – the catch: undocumented.
With the google help and some investigating I was able to get the prototypes, and they seem to work from XP all the way to Windows 7 in much the same way. At least there’s a way to enumerate those fonts and change to the one you like! I also found another undocumented function, SetConsoleIcon, to change the icon. A bonus!
The prototypes are:
typedef struct _CONSOLE_FONT {
DWORD index;
COORD dim;
} CONSOLE_FONT;
BOOL WINAPI SetConsoleFont(HANDLE hOutput, DWORD fontIndex);
BOOL WINAPI GetConsoleFontInfo(HANDLE hOutput, BOOL bMaximize, DWORD numFonts, CONSOLE_FONT* info);
DWORD WINAPI GetNumberOfConsoleFonts();
BOOL WINAPI SetConsoleIcon(HICON hIcon);
I’ve created two files ConsoleFont.h/cpp that use those prototypes to make the changes.
I’ve also created a managed wrapper (ConsoleHelper.cs) that can be used from managed code, like so:
static void Main(string[] args) {
var fonts = ConsoleHelper.ConsoleFonts;
for(int f = 0; f < fonts.Length; f++)
Console.WriteLine("{0}: X={1}, Y={2}",
fonts[f].Index, fonts[f].SizeX, fonts[f].SizeY);
ConsoleHelper.SetConsoleFont(5);
ConsoleHelper.SetConsoleIcon(SystemIcons.Information);
}
You may use these at your own risk, as these are undocumented functions, and can be changed in the future by Microsoft, although I believe they will eventually be documented.
There are still things missing. That mysterious console font table – I didn’t find a function that can be used to add entries to it. Perhaps it’s lurking in the registry somewhere. There’s no (exported) AddConsoleFont or something like that.
Happy fonting!