21

I have seen posts on changing console true type font and console colors (rgb) but nothing on setting or getting the console font size.

The reason I want to change the font size is because a grid is printed to the console, and the grid has many columns, so, it fits better with a smaller font. I'm wondering if it's possible to change it at runtime rather than allowing the default or configured fonts to take priority / override inheritance.

Chris
  • 2,340
  • 6
  • 40
  • 63
  • 1
    Shouldn't this really be left as a user option? The user can always change it through the application context menu, of course. – Noldorin Jul 02 '11 at 01:16
  • 1
    Why do you explicitly request an article? I can't really find anything on the matter though. – Teo Klestrup Röijezon Jul 02 '11 at 01:17
  • 1
    I didn't explicitly request an article, the question is; is it "possible to change console font size in c# .net?" – Chris Jul 02 '11 at 01:27
  • 1
    @Chris, In your original question you asked `Anyone see an article for this?`. In my book that counts as explicitly asking for an article. However, it's fine now with the rewording. – Teo Klestrup Röijezon Jul 02 '11 at 01:41
  • You should probably use the width of the console to help you decide how to format your table, instead of trying to muck with the font size or window size. Just my 2 cents. – Paul Wheeler Jul 02 '11 at 01:49
  • Maybe [this](http://stackoverflow.com/a/4589188/5996253) article can help you – Yitzhak Weinberg Sep 28 '16 at 08:17

4 Answers4

11

Maybe this article can help you

ConsoleHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;

namespace ConsoleExtender {
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct ConsoleFont {
        public uint Index;
        public short SizeX, SizeY;
    }

    public static class ConsoleHelper {
        [DllImport("kernel32")]
        public static extern bool SetConsoleIcon(IntPtr hIcon);

        public static bool SetConsoleIcon(Icon icon) {
            return SetConsoleIcon(icon.Handle);
        }

        [DllImport("kernel32")]
        private extern static bool SetConsoleFont(IntPtr hOutput, uint index);

        private enum StdHandle {
            OutputHandle = -11
        }

        [DllImport("kernel32")]
        private static extern IntPtr GetStdHandle(StdHandle index);

        public static bool SetConsoleFont(uint index) {
            return SetConsoleFont(GetStdHandle(StdHandle.OutputHandle), index);
        }

        [DllImport("kernel32")]
        private static extern bool GetConsoleFontInfo(IntPtr hOutput, [MarshalAs(UnmanagedType.Bool)]bool bMaximize, 
            uint count, [MarshalAs(UnmanagedType.LPArray), Out] ConsoleFont[] fonts);

        [DllImport("kernel32")]
        private static extern uint GetNumberOfConsoleFonts();

        public static uint ConsoleFontsCount {
            get {
                return GetNumberOfConsoleFonts();
            }
        }

        public static ConsoleFont[] ConsoleFonts {
            get {
                ConsoleFont[] fonts = new ConsoleFont[GetNumberOfConsoleFonts()];
                if(fonts.Length > 0)
                    GetConsoleFontInfo(GetStdHandle(StdHandle.OutputHandle), false, (uint)fonts.Length, fonts);
                return fonts;
            }
        }

    }
}

Here is how to use it to list true type fonts for console,

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);
}

Crucial functions: SetConsoleFont, GetConsoleFontInfo and GetNumberOfConsoleFonts. They're undocumented, so use at your own risk.

Sen Jacob
  • 3,384
  • 3
  • 35
  • 61
james_bond
  • 6,778
  • 3
  • 28
  • 34
  • 3
    Undocumented features are fun! Seriously though, good answer. – Paul Wheeler Jul 02 '11 at 01:31
  • 29
    Maybe, instead of pointing to another page, you can summarize why it helps? – the Tin Man Jul 02 '11 at 01:57
  • 9
    Whilst this may theoretically answer the question, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Kev Aug 01 '11 at 15:50
  • 4
    A link to a potential solution is always welcome, but please [add context around the link](http://meta.stackoverflow.com/a/8259/169503) so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. Take into account that being _barely more than a link to an external site_ is a possible reason as to [Why and how are some answers deleted?](http://stackoverflow.com/help/deleted-answers). – elixenide Nov 22 '16 at 03:06
  • 1
    It seems those undocumented functions do not work anymore in Windows 10 (unless you enable "legacy console" option in console properties). Beware. – tigrou Oct 03 '19 at 09:59
  • 2
    Broken link for me, also not Mac/Linux friendly :I – Max Jan 31 '20 at 10:29
  • 2
    Link is broken: Web archive: https://web.archive.org/web/20090808235410/http://blogs.microsoft.co.il/blogs/pavely/archive/2009/07/23/changing-console-fonts.aspx – Xonatron Mar 06 '20 at 15:46
9

In this thread I found a much more elegant solution that now works perfectly fine.

ConsoleHelper.cs:

using System;
using System.Runtime.InteropServices;

public static class ConsoleHelper
{
    private const int FixedWidthTrueType = 54;
    private const int StandardOutputHandle = -11;

    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern IntPtr GetStdHandle(int nStdHandle);

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    internal static extern bool SetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool MaximumWindow, ref FontInfo ConsoleCurrentFontEx);

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    internal static extern bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool MaximumWindow, ref FontInfo ConsoleCurrentFontEx);


    private static readonly IntPtr ConsoleOutputHandle = GetStdHandle(StandardOutputHandle);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct FontInfo
    {
        internal int cbSize;
        internal int FontIndex;
        internal short FontWidth;
        public short FontSize;
        public int FontFamily;
        public int FontWeight;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        //[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.wc, SizeConst = 32)]
        public string FontName;
    }

    public static FontInfo[] SetCurrentFont(string font, short fontSize = 0)
    {
        Console.WriteLine("Set Current Font: " + font);

        FontInfo before = new FontInfo
        {
            cbSize = Marshal.SizeOf<FontInfo>()
        };

        if (GetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref before))
        {

            FontInfo set = new FontInfo
            {
                cbSize = Marshal.SizeOf<FontInfo>(),
                FontIndex = 0,
                FontFamily = FixedWidthTrueType,
                FontName = font,
                FontWeight = 400,
                FontSize = fontSize > 0 ? fontSize : before.FontSize
            };

            // Get some settings from current font.
            if (!SetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref set))
            {
                var ex = Marshal.GetLastWin32Error();
                Console.WriteLine("Set error " + ex);
                throw new System.ComponentModel.Win32Exception(ex);
            }

            FontInfo after = new FontInfo
            {
                cbSize = Marshal.SizeOf<FontInfo>()
            };
            GetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref after);

            return new[] { before, set, after };
        }
        else
        {
            var er = Marshal.GetLastWin32Error();
            Console.WriteLine("Get error " + er);
            throw new System.ComponentModel.Win32Exception(er);
        }
    }
}

This way you can just do:

ConsoleHelper.SetCurrentFont("Consolas", 10);
maltejur
  • 131
  • 2
  • 2
1

After running the application (Ctrl + F5), right-click the title of the Console (it should say something like C:Windows\system32\cmd.exe) and select properties. Choose the "Font" tab, and you'll see the option to adjust the size.

Vicktor
  • 169
  • 2
  • 10
  • The OP is asking for a way to *programmatically* set the front size so your answer does not solve the needs. – Guy Levy Aug 20 '21 at 09:18
0

The console does not support changing font size at runtime. A list of the available methods for modifying the current console windows settings can be found on MSDN. My understanding is that this is because:

  1. The console is not a rich text interface, meaning it cannot display multiple fonts or font sizes.
  2. as Noldorin states, this is something that should be up to the user, for example a person with vision problems may elect for a large fontsize.
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41
  • 16
    real programmers think out the square – Chris Jul 02 '11 at 01:30
  • if the user changes the font size, ie. makes it smaller because they have a really really big monitor because their eyes are twice the size of the average persons eye, then my calculations will be affected, and when setting the console full screen (ie. maximized with custom buffer size on win7) it wont be the same if the user has Tampered with the default configuration. – Chris Jul 02 '11 at 01:38
  • @Chris, it seems like `Console` actually contains an option for setting the max window size. – Teo Klestrup Röijezon Jul 02 '11 at 01:42
  • ah, i had problems with this, but it seems to be working and looks the same with different font sizes now: Console.SetWindowSize(Console.LargestWindowWidth - 3, Console.LargestWindowHeight - 1); int hWnd = Process.GetCurrentProcess().MainWindowHandle.ToInt32(); Console.SetBufferSize(Console.LargestWindowWidth - 3, Console.LargestWindowHeight - 1); Move(); ShowWindow(hWnd, SW_MAXIMIZE); – Chris Jul 02 '11 at 02:51