Это, вероятно, территория noob, но что черт:
Я хочу встроить шрифты в мое приложение winforms, чтобы мне не пришлось беспокоиться о том, что они установлены на компьютере. Я немного искал сайт MSDN и нашел несколько советов о том, как использовать собственные вызовы Windows API, например, учебник Michael Caplans (sp?), Связанный с Скоттом Гензельманом. Теперь мне действительно нужно пройти через все эти неприятности? Не могу ли я просто использовать ресурсную часть моего приложения?
Если нет, я, вероятно, перейду к установочному маршруту. В таком случае я могу сделать это программно? Просто скопировав файл шрифта в папку Windows\Fonts?
Изменить: я знаю о проблемах с лицензированием, спасибо за беспокойство.
Это то, что сработало для меня в VS 2013, без необходимости использовать небезопасный блок.
Вставить ресурс
Загрузите шрифт в память
Добавить 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;
}
Properties.Resources
.
Properties.Resources
. Существует отдельная папка « Resources
которая создается в корне проекта при импорте ресурса.
// 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);
Не могу ли я использовать часть ресурса моего приложения?
Да, но для этого нужны собственные ресурсы, а не ресурсы .NET(т.е. с помощью rc.exe, компилятора собственных ресурсов).
Я перетащил случайно загруженный шрифт в мои ресурсы, и это сработало. Однако использует файл. Я думаю, вы можете использовать это также для установки шрифтов?
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);
}