如何在C#中的winforms应用程序中快速轻松地嵌入字体

这可能是noob领域,但是到底是什么:

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

如果不是,我可能会去安装路线。 在那种情况下,我可以通过编程方式进行操作吗? 只需将字体文件复制到Windows \ Fonts文件夹即可?

编辑:我知道许可问题,感谢关注。

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

嵌入资源

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

将字体加载到内存中

  1. using System.Drawing.Text;添加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. 在主窗体中添加标签,并添加一个load事件来设置Form1.cs中的字体:

     private void Form1_Load(object sender, EventArgs e) { label1.Font = myFont; } 
 // 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); 

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

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

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

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