C#在运行时修改控制台字体、字体大小?

Posted

技术标签:

【中文标题】C#在运行时修改控制台字体、字体大小?【英文标题】:C# modify console font, font size at runtime? 【发布时间】:2018-04-11 08:58:44 【问题描述】:

我正在创建rougelike 并确保我的游戏正确显示,我想在运行时更改控制台字体和字体大小。

我对编程和 c# 非常陌生,所以我希望可以用我或其他任何人都可以轻松实现的方式来解释这一点。

resource 列出了 CONSOLE_FONT_INFOEX 结构的完整语法:

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;

具体来说,我想在运行时将控制台字体更改为 NSimSum 并将字体大小更改为 32。

编辑 1:我能否解释一下如何使用来自 this 帖子的 SetCurrentConsoleFontEx function。我不明白该函数需要处于什么上下文中。我尝试了Console.SetCurrentConsoleFontEx,但 vs 没有给我任何选项。

编辑 2:this 论坛帖子似乎详细介绍了一种更改字体大小的简单方法,但它是特定于 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);

【问题讨论】:

Changing font in a Console window in .NET的可能重复 在Changing font in a Console window in .NET 中没有解释如何实现我在字体类型上苦苦挣扎的代码。帖子中没有回答字体大小。 我认为我的帖子应该被删除,因为它不清楚并且缺少我找到的新信息。相关答案是来自 msdn 的复制和粘贴,并附有“您尝试过吗”的说明,而另一个答案仅适用于 winfroms。我打算发一个新帖子,感谢发帖者试图帮助我解决我模糊的帖子。 【参考方案1】:

你试过了吗

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

更多详情请参考https://msdn.microsoft.com/en-us/library/system.console(v=vs.110).aspx

【讨论】:

所有代码中是否有几行代码可以用来更改字体和字体大小?很抱歉,但我不明白其中大部分是如何要求的 你需要从 Main 方法中过滤代码,rest 将是完全需要的,请尝试运行它并调试它,它将帮助你不运行但了解它是如何工作的 我不知道如何在我的代码中实现这一点,我想我想改变字体大小。有点令人震惊,没有 Console.SetCurrentConsoleFontSize(32) 但我想如果它那么容易我就不会卡住了。 它给了我在@SetCurrentConsoleFontEx@线上使用受保护内存的例外情况。 您必须在构建中启用“不安全”代码(这很重要,应该在答案中提及)。在 Visual Studio 中,这是在项目属性构建选项卡中完成的(右键单击解决方案资源管理器中的项目 > 属性)。您在 Main 方法中设置它(像往常一样),其余的是您需要复制到项目中的互操作内容。【参考方案2】:

您可能会考虑的另一种选择是创建一个 winforms 应用程序并改用 RichTextBox。我想这取决于您需要多少依赖任何内置控制台功能。

请注意使用一些自定义函数来更轻松地编写彩色文本。

你可以试试这样的:

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;
    

输出

【讨论】:

没有更简单的方法吗?是否有几行代码可以用来更改字体和字体大小? 在上面的代码中,就是这一行:console.Font = new Font("Consolas", 20);。但在常规控制台中我一无所知。 我不知道 winfrom 是什么,直到我用谷歌搜索它,我决定在控制台中做这个,我认为代码在控制台中不起作用? 如果我不知道如何从控制台设置字体/大小,我会切换到 winforms,谢谢您的回答 感谢 Rufus L 非常有创意。

以上是关于C#在运行时修改控制台字体、字体大小?的主要内容,如果未能解决你的问题,请参考以下文章

C# 如何改变控制台输出字体颜色

c#控件多行显示不同字体大小

IntelJIdea 如何修改控制台字体大小和主题

如何调整eclipse字体大小

新手小白学JAVA_IDEA修改编辑与控制台字体大小

如何在 WPF C# 中更改验证结果的字体大小