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

时间:2009-02-17 09:59:41

标签: c# fonts embedding

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

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

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

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

5 个答案:

答案 0 :(得分:43)

这在VS 2013中对我有用,无需使用不安全的阻止。

嵌入资源

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

    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);
              }
          }
      }
      
    3. 使用您的字体

      1. 在主窗体中添加标签,并添加一个load事件来设置Form1.cs中的字体:

        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Font = myFont;
        }
        

答案 1 :(得分:6)

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

  

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

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

答案 4 :(得分:-1)

我会采用骑士的嵌入字体的方法,但是当涉及到更改字体时,我选择以下代码:

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

有关更多信息:Easiest way to change font and font size