Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing font in a Console window in C#

I have a program, written in C#, that uses characters not available in Raster fonts. So I want to change font to Lucida Console.

To change Console font programatically, I use SetCurrentConsoleFontEx() with this code (Source: MSDN Console Class) but I got an System.AccessViolationException on call SetCurrentConsoleFontEx().

Could anyone help me?

Thank's for your help.

using System;
using System.Linq;
using System.Runtime.InteropServices;


namespace ConsoleExtender 
{
  public static class ConsoleHelper
  {
      [StructLayout(LayoutKind.Sequential)]
      internal unsafe struct CONSOLE_FONT_INFO_EX
      {
          internal uint cbSize;
          internal uint nFont;
          internal COORD dwFontSize;
          internal int FontFamily;
          internal int FontWeight;
          internal fixed char FaceName[LF_FACESIZE];
      }

      [StructLayout(LayoutKind.Sequential)]
      internal struct COORD
      {
          internal short X;
          internal short Y;

          internal COORD(short x, short y)
          {
              X = x;
              Y = y;
          }
      }
      [DllImport("kernel32.dll", SetLastError = true)]
      static extern IntPtr GetStdHandle(int nStdHandle);

      [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
      static extern bool GetCurrentConsoleFontEx(
             IntPtr consoleOutput,
             bool maximumWindow,
             ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx);

      [DllImport("kernel32.dll", SetLastError = true)]
      static extern bool SetCurrentConsoleFontEx(
             IntPtr consoleOutput,
             bool maximumWindow,
             CONSOLE_FONT_INFO_EX consoleCurrentFontEx);

      private const int STD_OUTPUT_HANDLE = -11;
      private const int TMPF_TRUETYPE = 4;
      private const int LF_FACESIZE = 32;
      private static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

      public static void SetConsoleFont(string fontName = "Lucida Console") 
      {
          unsafe
          {
            IntPtr hnd = GetStdHandle(STD_OUTPUT_HANDLE);
            if (hnd != INVALID_HANDLE_VALUE)
            {
                CONSOLE_FONT_INFO_EX info = new CONSOLE_FONT_INFO_EX();
                info.cbSize = (uint)Marshal.SizeOf(info);

                // Set console font to Lucida Console.
                CONSOLE_FONT_INFO_EX newInfo = new CONSOLE_FONT_INFO_EX();
                newInfo.cbSize = (uint)Marshal.SizeOf(newInfo);
                newInfo.FontFamily = TMPF_TRUETYPE;
                IntPtr ptr = new IntPtr(newInfo.FaceName);
                Marshal.Copy(fontName.ToCharArray(), 0, ptr, fontName.Length);

                // Get some settings from current font.
                newInfo.dwFontSize = new COORD(info.dwFontSize.X, info.dwFontSize.Y);
                newInfo.FontWeight = info.FontWeight;
                SetCurrentConsoleFontEx(hnd, false, newInfo);
            }
          }
      }
  }
}
like image 555
LeMoussel Avatar asked Dec 17 '13 10:12

LeMoussel


People also ask

How do I change the font in Windows Command Prompt?

Right Click the top bar of the Command Prompt Window (i.e. Right Click the words "Command Prompt" on the top left) and select Properties. There you can change Font, Size, Color and other options.

How do I increase font size in console?

Right click on the console window title bar, select Defaults, switch to tab Font and choose your desired font and size.


2 Answers

There's two problems with the way you've defined those API calls.

First, the documentation for SetCurrentConsoleFontEx says:

lpConsoleCurrentFontEx

A pointer to a CONSOLE_FONT_INFOEX structure that contains the font information.

So the third parameter needs to be passed by reference:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetCurrentConsoleFontEx(
    IntPtr consoleOutput,
    bool maximumWindow,
    ref CONSOLE_FONT_INFO_EX consoleCurrentFontEx);

and you need to call the method like this:

SetCurrentConsoleFontEx(hnd, false, ref newInfo);

Secondly, the FaceName field in the CONSOLE_FONT_INFO_EX structure is an array of Unicode characters. I had to specify the CharSet to get it to work:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal unsafe struct CONSOLE_FONT_INFO_EX
{
    internal uint cbSize;
    internal uint nFont;
    internal COORD dwFontSize;
    internal int FontFamily;
    internal int FontWeight;
    internal fixed char FaceName[LF_FACESIZE];
}
like image 66
reduckted Avatar answered Oct 26 '22 14:10

reduckted


I don't know why this works but if you go to Properties -> Build and disable "Prefer 32-bit", you won't get the error any more.

like image 29
Robert Calceanu Avatar answered Oct 26 '22 12:10

Robert Calceanu