Как быстро и легко встроить шрифты в приложение winforms в C #

23

Это, вероятно, территория noob, но что черт:

Я хочу встроить шрифты в мое приложение winforms, чтобы мне не пришлось беспокоиться о том, что они установлены на компьютере. Я немного искал сайт MSDN и нашел несколько советов о том, как использовать собственные вызовы Windows API, например, учебник Michael Caplans (sp?), Связанный с Скоттом Гензельманом. Теперь мне действительно нужно пройти через все эти неприятности? Не могу ли я просто использовать ресурсную часть моего приложения?

Если нет, я, вероятно, перейду к установочному маршруту. В таком случае я могу сделать это программно? Просто скопировав файл шрифта в папку Windows\Fonts?

Изменить: я знаю о проблемах с лицензированием, спасибо за беспокойство.

  • 2
    Вы можете сделать это, но также помните, что как программные шрифты также имеют лицензии, и вам необходимо убедиться, что вы не нарушаете никаких лицензий, которые запрещают встраивание и развертывание.
Теги:
fonts
embedding

4 ответа

28

Это то, что сработало для меня в VS 2013, без необходимости использовать небезопасный блок.

Вставить ресурс

  • Дважды щелкните значок Resource.resx, а на панели инструментов дизайнера нажмите Добавить ресурс/Добавить существующий файл и выберите файл .ttf.
  • В своем проводнике решений щелкните правой кнопкой мыши ваш .ttf файл (теперь в папке "Ресурсы" ) и перейдите в "Свойства". Установите действие сборки на "Встроенный ресурс"

Загрузите шрифт в память

  • Добавить using System.Drawing.Text; в файл Form1.cs

  • Добавьте код выше и внутри вашего конструктора по умолчанию, чтобы создать шрифт в памяти (без использования "небезопасных", как показали другие примеры). Ниже приведена моя вся Form1.cs:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Reflection;
    
    using System.Drawing.Text;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont,
                IntPtr pdv, [System.Runtime.InteropServices.In] ref uint pcFonts);
    
            private PrivateFontCollection fonts = new PrivateFontCollection();
    
            Font myFont;
    
            public Form1()
            {
                InitializeComponent();
    
                byte[] fontData = Properties.Resources.MyFontName;
                IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
                System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
                uint dummy = 0;
                fonts.AddMemoryFont(fontPtr, Properties.Resources.MyFontName.Length);
                AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.MyFontName.Length, IntPtr.Zero, ref dummy);
                System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
    
                myFont = new Font(fonts.Families[0], 16.0F);
            }
        }
    }
    

Используйте свой шрифт

  • Добавьте метку в свою основную форму и добавьте событие загрузки, чтобы установить шрифт в Form1.cs:

    private void Form1_Load(object sender, EventArgs e)
    {
        label1.Font = myFont;
    }
    
  • 0
    Это не работает для меня. Мой шрифт не отображается в разделе Properties.Resources .
  • 0
    @JamesDonnelly Это не должно появляться в Properties.Resources . Существует отдельная папка « Resources которая создается в корне проекта при импорте ресурса.
Показать ещё 2 комментария
4
// specify embedded resource name
string resource = "embedded_font.PAGAP___.TTF";

// receive resource stream
Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);

// create an unsafe memory block for the font data
System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);

// create a buffer to read in to
byte[] fontdata = new byte[fontStream.Length];

// read the font data from the resource
fontStream.Read(fontdata, 0, (int)fontStream.Length);

// copy the bytes to the unsafe memory block
Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);

// pass the font to the font collection
private_fonts.AddMemoryFont(data, (int)fontStream.Length);

// close the resource stream
fontStream.Close();

// free up the unsafe memory
Marshal.FreeCoTaskMem(data);
1

Не могу ли я использовать часть ресурса моего приложения?

Да, но для этого нужны собственные ресурсы, а не ресурсы .NET(т.е. с помощью rc.exe, компилятора собственных ресурсов).

0

Я перетащил случайно загруженный шрифт в мои ресурсы, и это сработало. Однако использует файл. Я думаю, вы можете использовать это также для установки шрифтов?

public Form1()
{
    string filename = @"C:\lady.gaga";
    File.WriteAllBytes(filename, Resources.KBREINDEERGAMES);
    PrivateFontCollection pfc = new PrivateFontCollection();
    pfc.AddFontFile(filename);

    Label label = new Label();
    label.AutoSize = true;
    label.Font = new Font(pfc.Families[0], 16);
    label.Text = "hello world";
    Controls.Add(label);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню