【问题标题】:Use resource font directly in VB.net/C#在 VB.net/C# 中直接使用资源字体
【发布时间】:2023-04-09 03:42:01
【问题描述】:

如何在VB.net/C#中为独立应用[桌面应用]直接使用资源字体而不在本地文件系统中保存字体?

【问题讨论】:

  • @SamSol:没有 CS.NET 这样的东西。你从哪里听说过这个?该语言只是“C#”。

标签: c# vb.net winforms fonts resources


【解决方案1】:

这是可能的,您需要使用 PrivateFontCollection.AddMemoryFont() 方法。例如,我添加了一个名为“test.ttf”的字体文件作为资源并像这样使用它:

using System.Drawing.Text;
using System.Runtime.InteropServices;
...
public partial class Form1 : Form {
    private static PrivateFontCollection myFonts;
    private static IntPtr fontBuffer;

    public Form1() {
        InitializeComponent();
        if (myFonts == null) {
            myFonts = new PrivateFontCollection();
            byte[] font = Properties.Resources.test;
            fontBuffer = Marshal.AllocCoTaskMem(font.Length);
            Marshal.Copy(font, 0, fontBuffer, font.Length);
            myFonts.AddMemoryFont(fontBuffer, font.Length);
        }
    }

    protected override void OnPaint(PaintEventArgs e) {
        FontFamily fam = myFonts.Families[0];
        using (Font fnt = new Font(fam, 16)) {
            TextRenderer.DrawText(e.Graphics, "Private font", fnt, Point.Empty, Color.Black);
            //e.Graphics.DrawString("Private font", fnt, Brushes.Black, 0, 0);
        }
    }
}

请注意fontBuffer 变量是有意静态的。使用 AddMemoryFont() 时内存管理很困难,只要字体可以使用且 PrivateFontCollection 尚未释放,内存就需要保持有效。如果您没有该保证,请务必不要调用 Marshal.FreeCoTaskMem(),这是一个非常常见的错误,导致很难诊断文本损坏。只有在幸运时才会收到 AccessViolationException。简单的解决方案是让它在程序的生命周期内保持有效。

【讨论】:

  • @HansPassant : 如果我要添加的字体文​​件具有 '.bin' 扩展名而不是 '.ttf' 怎么办
  • 我需要在工作之前使用 PInvoke。必须使用函数AddFontMemResourceEx...也许是因为PrivateFontCollection.AddMemoryFont() 期望字体在系统内存中。我还想知道这是否与我正在更改文本框的字体这一事实有关,而不是与字体显式渲染有关。 (但使用 PrivateFontCollection.AddFontFile() 在没有 PInvoke 功能的情况下仍然有效)。
【解决方案2】:

您是在谈论使用应用程序包装字体吗?如是。 看看这个: http://msdn.microsoft.com/en-us/library/ms753303.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多