C# 如何在WinForms应用程序中嵌入自己的字体?

C# 如何在WinForms应用程序中嵌入自己的字体?,c#,fonts,embedding,C#,Fonts,Embedding,我想在我的WinForms应用程序中嵌入字体,这样我就不必担心它们被安装在机器上。我在MSDN网站上搜索了一下,找到了一些关于使用本机Windows API调用的提示,例如Scott Hanselman链接的Michael Caplan(sp?)教程。现在,我真的要经历这些麻烦吗?我不能只使用应用程序的资源部分吗 如果不是,我可能会选择安装路线。在这种情况下,我可以通过编程实现吗?只需将字体文件复制到Windows\Fonts文件夹 我知道许可问题 我不能只使用应用程序的资源部分吗 是的,但必须

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

如果不是,我可能会选择安装路线。在这种情况下,我可以通过编程实现吗?只需将字体文件复制到Windows\Fonts文件夹

我知道许可问题

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


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

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

嵌入资源

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

  • 使用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);
            }
        }
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        label1.Font = myFont;
    }
    
  • 使用您的字体

  • 向主窗体添加标签,并添加加载事件以设置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);
            }
        }
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        label1.Font = myFont;
    }
    
  • 我在我的资源中拖拽并丢弃了一个,这起了作用。但是使用了一个文件。我想你也可以用它来安装字体

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

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

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

    有关更多信息:

    您可以这样做,但也要注意,与软件字体一样,字体也有许可证,您需要确保您没有违反任何禁止嵌入和部署的许可证。这对我不适用。我的字体不显示在
    Properties.Resources
    @JamesDonnelly下,它不应该显示在
    Properties.Resources
    下。导入资源时,会在项目根目录下创建一个名为
    Resources
    的单独文件夹。多个ttf(如常规、粗体和斜体)如何?抱歉,我不明白。在哪里可以设置字体名称,以便它知道从resources文件夹中获取哪个文件?字体在那里,但我看不到它在提供的代码中的调用位置。这并不能真正回答问题。哥们,它解决了更改字体的问题。如果你想加粗你的字体,那么你可以很容易地改变它使用我提供的代码,改变字体大小?使用code@Jebbidan-在我的机器上,由于专利和版税原因,“Heletivica”字体更改为“Arial”,因此Microsoft不会被起诉。问题是如何将非标准字体嵌入到应用程序中,而不是为现有字体创建
    font
    对象。