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

发布于 2024-07-14 11:47:44 字数 291 浏览 7 评论 0原文

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

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

我知道许可问题。

I want to embed fonts in my WinForms application so that I don't have to worry about them being installed on the machine. I've searched a bit on the MSDN site and found a few hints about using native Windows API calls, for instance Michael Caplan's (sp?) tutorial linked to by Scott Hanselman. Now, do I really have to go through all that trouble? Can't I just use the resource part of my app?

If not I'll probably go the installing route. In that case, can I do that programmatically? By just copying the font file to the Windows\Fonts folder?

I am aware of licensing issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

沫雨熙 2024-07-21 11:47:45
// 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);
// 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);
毁我热情 2024-07-21 11:47:45

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

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

I dragged and dropped a randomly downloaded font into my resources and this worked. Uses a file though. I guess you can use this as well to install fonts ?

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);
}
佼人 2024-07-21 11:47:45

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

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

Can't I just use the resource part of my app?

Yes, but need to be native resources rather than .NET resources (i.e. using rc.exe, the native resource compiler).

安稳善良 2024-07-21 11:47:45

我将采用骑士的方式嵌入字体,但当涉及到更改字体时,我选择此代码:

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

有关更多信息:更改字体和字体大小的最简单方法

i will go with knighter's way of embedding a font but when it comes to changing your font I choose this code:

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

for more information: Easiest way to change font and font size

聚集的泪 2024-07-21 11:47:44

这就是我在 VS 2013 中的工作,无需使用不安全的块。

嵌入资源

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

将字体加载到内存中

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

  2. 在默认构造函数的上方和内部添加代码,以在内存中创建字体(不使用“不安全”,如其他示例所示)。 下面是我的整个 Form1.cs:

    使用系统; 
      使用 System.Collections.Generic; 
      使用 System.ComponentModel; 
      使用系统数据; 
      使用系统绘图; 
      使用 System.Linq; 
      使用系统文本; 
      使用 System.Threading.Tasks; 
      使用 System.Windows.Forms; 
      使用系统反射; 
    
      使用 System.Drawing.Text; 
    
      命名空间 WindowsFormsApplication1 
      { 
          公共部分类 Form1 :表格 
          { 
              [System.Runtime.InteropServices.DllImport(“gdi32.dll”)] 
              私有静态 extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, 
                  IntPtr pdv, [System.Runtime.InteropServices.In] ref uint pcFonts); 
    
              私人 PrivateFontCollection 字体 = new PrivateFontCollection(); 
    
              字体 myFont; 
    
              公共表格1() 
              { 
                  初始化组件(); 
    
                  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 虚拟 = 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 = 新字体(fonts.Families[0], 16.0F); 
              } 
          } 
      } 
      

使用你的字体

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

    private void Form1_Load(对象发送者,EventArgs e) 
      { 
          label1.Font = myFont; 
      } 
      

This is what worked for me in VS 2013, without having to use an unsafe block.

Embed the resource

  1. Double-click Resources.resx, and in the toolbar for the designer click Add Resource/Add Existing File and select your .ttf file
  2. In your solution explorer, right-click your .ttf file (now in a Resources folder) and go to Properties. Set the Build Action to "Embedded Resource"

Load the font into memory

  1. Add using System.Drawing.Text; to your Form1.cs file

  2. Add code above and inside your default constructor to create the font in memory (without using "unsafe" as other examples have shown). Below is my entire 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);
            }
        }
    }
    

Use your font

  1. Add a label to your main form, and add a load event to set the font in Form1.cs:

    private void Form1_Load(object sender, EventArgs e)
    {
        label1.Font = myFont;
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文