3

I'm in the process of creating a rougelike and to assure my game displays correctly I am wanting to change the console font and font size at runtime.

I am very noob to programming and c# so I'm hoping this can be explained in a way I or anyone else can easily implement.

This resource list the full syntax of the CONSOLE_FONT_INFOEX structure:

typedef struct _CONSOLE_FONT_INFOEX {
  ULONG cbSize;
  DWORD nFont;
  COORD dwFontSize;
  UINT  FontFamily;
  UINT  FontWeight;
  WCHAR FaceName[LF_FACESIZE];
} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX;

Specifically I'm wanting to change the console font to NSimSum and font size to 32 at runtime.

EDIT 1: Could I have it explained how to use the SetCurrentConsoleFontEx function from this post. I don't understand what context the function needs to be in. I tried Console.SetCurrentConsoleFontEx but vs gave me no options.

EDIT 2: this forum post seems to detail a simple method of changing font size but is it specific to c++?

void setFontSize(int FontSize)
{
    CONSOLE_FONT_INFOEX info = {0};
    info.cbSize       = sizeof(info);
    info.dwFontSize.Y = FontSize; // leave X as zero
    info.FontWeight   = FW_NORMAL;
    wcscpy(info.FaceName, L"Lucida Console");
    SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), NULL, &info);
}
Trr1ppy
  • 49
  • 1
  • 2
  • 11
  • Possible duplicate of [Changing font in a Console window in .NET](https://stackoverflow.com/questions/1802600/changing-font-in-a-console-window-in-net) – The Bearded Llama Oct 30 '17 at 11:46
  • In [Changing font in a Console window in .NET](https://stackoverflow.com/questions/1802600/changing-font-in-a-console-window-in-net) it isn't explained how to implement the code which is where I'm struggling with font type. Font size isn't answered in the post. – Trr1ppy Oct 30 '17 at 15:04
  • I think my post should be deleted since its not clear and lacks new information I have found. The relevant answer is a copy and paste from msdn with an explination of "Have you tried this" and the other answer only applies to winfroms. I am planning to make a new post, Thanks posters for trying to help me with my vague post. – Trr1ppy Oct 31 '17 at 06:41

2 Answers2

3

Another alternative that you might look into is to create a winforms app and use a RichTextBox instead. I guess it depends on how much you need to rely on any built-in console features.

Notice the use of some custom functions to make writing colored text easier.

You can try out something like this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    RichTextBox console = new RichTextBox();

    private void Form1_Load(object sender, EventArgs e)
    {
        console.Size = this.ClientSize;
        console.Top = 0;
        console.Left = 0;
        console.BackColor = Color.Black;
        console.ForeColor = Color.White;
        console.WordWrap = false;
        console.Font = new Font("Consolas", 12);            

        this.Controls.Add(console);
        this.Resize += Form1_Resize;

        DrawDiagram();
    }

    private void DrawDiagram()
    {
        WriteLine("The djinni speaks. \"I am in your debt. I will grant one wish!\"--More--\n");
        Dot(7);
        Diamond(2);
        WriteLine("....╔═══════╗..╔═╗");
        Dot(8);
        Diamond(2);
        WriteLine("...║..|....║..║.╠══════╦══════╗");
        Dot(9);
        Diamond(2);
        Write("..║.|.....║..║.║      ║.");
        Write('&', Color.DarkRed);
        Dot(4);
        WriteLine("║");
    }

    private void Dot(int qty)
    {
        Write('.', qty);
    }

    private void WriteLine(string text)
    {
        Write($"{text}\n");
    }

    private void Diamond(int qty)
    {
        Write('♦', qty, Color.Blue);
    }

    private void Write(char character, Color color)
    {
        Write(character, 1, color);
    }

    private void Write(char character, int qty)
    {
        Write(character, qty, Color.White);
    }

    private void Write(char character, int qty, Color color)
    {
        Write(new string(character, qty), color);
    }

    private void Write(string text)
    {
        Write(text, Color.White);
    }

    private void Write(string text, Color color)
    {
        var originalColor = console.SelectionColor;
        console.SelectionColor = color;
        console.AppendText(text);
        console.SelectionColor = originalColor;
    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        console.Size = this.ClientSize;
    }
}

Output

enter image description here

Rufus L
  • 36,127
  • 5
  • 30
  • 43
0

Have you tried this

using System;
using System.Runtime.InteropServices;

public class Example
{
   [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 unsafe void Main()
   {
      string fontName = "Lucida Console";
      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);
         bool tt = false;
         // First determine whether there's already a TrueType font.
         if (GetCurrentConsoleFontEx(hnd, false, ref info)) {
            tt = (info.FontFamily & TMPF_TRUETYPE) == TMPF_TRUETYPE;
            if (tt) {
               Console.WriteLine("The console already is using a TrueType font.");
               return;
            }
            // 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);
         }
      }    
    }

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

      internal COORD(short x, short y)
      {
         X = x;
         Y = y;
      }
   }

   [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];
   } 
}

Refer https://msdn.microsoft.com/en-us/library/system.console(v=vs.110).aspx for more details

Ipsit Gaur
  • 2,872
  • 1
  • 23
  • 38
  • 1
    Is there a couple lines among all that code that I can use to only change font and font size? I'm sorry but I don't understand how most of it is required – Trr1ppy Oct 30 '17 at 14:11
  • You will need to filter code from Main method rest will be completely required, please try running it and debug it, it will help you not running but understanding how is it working – Ipsit Gaur Oct 30 '17 at 14:23
  • I have no idea how to implement this into my code, I think I'm in over my head trying to change font size. kinda shocking there is no Console.SetCurrentConsoleFontSize(32) but I guess if it was that easy I wouldnt be stuck. – Trr1ppy Oct 30 '17 at 14:37
  • 1
    It gives me an exception for using protected memory on line @SetCurrentConsoleFontEx@. – Zéiksz Apr 24 '18 at 13:01
  • 1
    You must enable "unsafe" code in the build (this is important and *should* be mentioned in the answer). In Visual Studio this is done in the Project properties build tab (right click the project in Solution Explorer > Properties). You set it up in the Main method (like usual), the rest is interop stuff that you need to just copy into your project. – Adam Plocher Feb 04 '20 at 17:44
  • I always get "The console already is using a TrueType font.". – miran80 Jun 09 '20 at 02:03