38

我想在我的 WinForms 应用程序中嵌入字体,这样我就不必担心它们会安装在机器上。我在 MSDN 网站上进行了一些搜索,发现了一些关于使用本机 Windows API 调用的提示,例如 Scott Hanselman 链接到的 Michael Caplan 的 (sp?) 教程。现在,我真的必须经历所有这些麻烦吗?我不能只使用我的应用程序的资源部分吗?

如果没有,我可能会走安装路线。在那种情况下,我可以以编程方式做到这一点吗?通过将字体文件复制到 Windows\Fonts 文件夹?

我知道许可问题。

4

5 回答 5

58

这就是在 VS 2013 中对我有用的方法,而不必使用不安全的块。

嵌入资源

  1. 双击 Resources.resx,然后在设计器的工具栏中单击 Add Resource/Add Existing File 并选择您的 .ttf 文件
  2. 在您的解决方案资源管理器中,右键单击您的 .ttf 文件(现在位于资源文件夹中)并转到属性。将构建操作设置为“嵌入式资源”

将字体加载到内存中

  1. 添加using System.Drawing.Text;到您的 Form1.cs 文件

  2. 在默认构造函数的上方和内部添加代码以在内存中创建字体(不使用其他示例所示的“不安全”)。下面是我的整个 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;
    }
    
于 2014-05-07T13:40:59.073 回答
8
// 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);
于 2011-05-26T09:29:39.820 回答
6

我将随机下载的字体拖放到我的资源中,这很有效。虽然使用文件。我想您也可以使用它来安装字体?

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);
}
于 2014-07-21T12:12:12.247 回答
2

我不能只使用我的应用程序的资源部分吗?

可以,但需要是本地资源而不是 .NET 资源(即使用 rc.exe,本地资源编译器)。

于 2009-02-17T15:02:19.693 回答
-4

我将采用 knighter 嵌入字体的方式,但在更改字体时,我选择以下代码:

YourLabel.Font = new Font("Arial", 24,FontStyle.Bold);

欲了解更多信息:更改字体和字体大小的最简单方法

于 2020-08-31T06:40:51.720 回答