Как быстро и легко встроить шрифты в приложение winforms в C # - PullRequest
29 голосов
/ 17 февраля 2009

Это, вероятно, территория нубов, но какого черта:

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

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

Редактировать: Мне известны проблемы с лицензированием, спасибо за беспокойство.

Ответы [ 4 ]

44 голосов
/ 07 мая 2014

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

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

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

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

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

  2. Добавьте код выше и внутри вашего конструктора по умолчанию, чтобы создать шрифт в памяти (без использования «unsafe», как показали другие примеры). Ниже весь мой 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);
            }
        }
    }
    

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

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

    private void Form1_Load(object sender, EventArgs e)
    {
        label1.Font = myFont;
    }
    
6 голосов
/ 26 мая 2011
// 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);
3 голосов
/ 21 июля 2014

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

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);
}
1 голос
/ 17 февраля 2009

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

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

...