我想在我的WinForms应用程序中嵌入字体,这样我就不用担心它们是否已安装在计算机上。我在MSDN网站上搜索了一些内容,并找到了一些有关使用本地Windows API调用的提示,例如由Scott Hanselman链接到的Michael Caplan的教程。现在,我真的必须费这么大劲吗?我不能只使用我的应用程序的资源部分吗?
如果不行,我可能会选择安装路线。在那种情况下,我能否通过将字体文件复制到Windows \ Fonts文件夹来以编程方式完成?
我意识到有许可问题。
我想在我的WinForms应用程序中嵌入字体,这样我就不用担心它们是否已安装在计算机上。我在MSDN网站上搜索了一些内容,并找到了一些有关使用本地Windows API调用的提示,例如由Scott Hanselman链接到的Michael Caplan的教程。现在,我真的必须费这么大劲吗?我不能只使用我的应用程序的资源部分吗?
如果不行,我可能会选择安装路线。在那种情况下,我能否通过将字体文件复制到Windows \ Fonts文件夹来以编程方式完成?
我意识到有许可问题。
以下是我在VS 2013中实现的方法,无需使用unsafe块。
嵌入资源
将字体加载到内存中
在Form1.cs文件中添加using System.Drawing.Text;
在默认构造函数上方和内部添加代码以在内存中创建字体(不使用其他示例中显示的“不安全”方式)。下面是我整个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);
}
}
}
使用您的字体
在主表单中添加标签,并在Form1.cs中添加加载事件来设置字体:
private void Form1_Load(object sender, EventArgs e)
{
label1.Font = myFont;
}
Properties.Resources
下。当你导入资源时,在项目根目录下会创建一个名为 Resources
的单独文件夹。”请注意,我已经尽力使翻译更加通俗易懂了,但并没有改变原文的含义。 - PyroglyphMyFontName
替换为您的字体的实际名称。 - Ooker// 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);
private_fonts
定义在哪里? - MetaFightpublic 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,本地资源编译器)。
我会采用Knighter的嵌入字体方法,但是当涉及到更改字体时,我选择这段代码:
YourLabel.Font = new Font("Arial", 24,FontStyle.Bold);
更多信息请参见:最简单的更改字体和字号的方法
Font
对象。 - Dave Cousineau