Проблемы с отображением юникодных карт в разных версиях Windows - PullRequest
0 голосов
/ 17 декабря 2018

Используя c # .net 4.7.1, я пытаюсь создать консольное приложение для игры в блэкджек, и у меня возникают проблемы с отображением мастей карт для вывода на консоль в разных версиях Windows.Для Windows 7 это метод Main, который правильно отображает костюмы:

static void Main(string[] args)
{
    string[] Suits = new string[] { "♠", "♣", "♥", "♦" };
    Methods.Print(Suits[0] + " " + Suits[1] + " " + Suits[2] + " " + Suits[3]);
    Console.ReadLine();
    ....
}

костюмы отображаются так, как я хочу, например:

enter image description here

Но если я запускаю свою программу с этим методом Main на моем компьютере с Windows 10, они отображаются так:

enter image description here

Я обнаружил, что если я включу эту строку в мой метод Main на моем компьютере с Windows 10, то костюмы будут отображаться так, как я хочу:

Console.OutputEncoding = System.Text.Encoding.UTF8;

Но тогда это делаеткостюмы не отображаются правильно на моем компьютере с Windows 7.Может кто-нибудь помочь мне с тем, как я могу правильно отобразить эти масти карт независимо от того, на какой ОС Windows работает программа?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Спасибо @tymtam за понимание проблемы, с которой я столкнулся.Я рассмотрел возможность изменения шрифта консоли в качестве решения.Я нашел эту статью, в которой показано, как программно изменить шрифт консоли на Lucida Console, который является шрифтом истинного типа.Вот мой отформатированный код по этой ссылке:

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

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

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

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int SetConsoleFont(IntPtr hOut, uint dwFontNum);

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

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

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

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

        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, ref newInfo);
                }
            }
        }

        static void Main(string[] args)
        {            
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            SetConsoleFont();
            ....
        }

Две вещи на заметку

  1. Мне пришлось добавить это, используя оператор, чтобы он работал:

    using System.Runtime.InteropServices;

  2. Я должен был установить флажок Allow unsafe code, расположенный на экране Project>Properties>Build, как показано ниже:

enter image description here

После внесения этих изменений программа работает как в Windows 7, так и в Windows 10 и отображает масти карт, как я хочу.Как я уже говорил ранее, у меня нет доступа к машинам, на которых установлены другие версии Windows, поэтому я могу только сказать, что это точно работает в Windows 7 и Windows 10.

0 голосов
/ 17 декабря 2018

Если вы хотите, чтобы он работал надежно в консоли, вот мое решение:

static void Main(string[] args)
{
    Console.WriteLine("D, C, H, S");
    Console.ReadLine();
}

Вот еще 2 варианта:

  • Проверка версий Windows и тестирование всех сценариевиспользуя , , , и Encoding.UTF8;
  • приложение Gui.

Windows 7

Проблема сКонсоль Windows7 и

Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine("♠, ♣, ♥, ♦");
Console.ReadLine();

- наиболее вероятный шрифт в консольном приложении.

Из Свойство Console.OutputEncoding :

Обратите внимание, чтоДля успешного отображения символов Unicode на консоли требуется следующее:

Для отображения символов консоль должна использовать шрифт TrueType, например, Lucida Console или Consolas.

Вы можете изменить шрифтв свойствах приложения Console:

enter image description here

...