2010-05-28 9 views
7

¿Cómo se usa la fuente de recursos directamente sin guardar la fuente en el sistema de archivos local para la aplicación independiente [aplicación de escritorio] en VB.net/C#?Utilice la fuente de recursos directamente en VB.net/C#

+0

@SamSol: no existe tal cosa como CS.NET. ¿Dónde escuchaste eso? El lenguaje es solo "C#". –

Respuesta

14

eso es posible, necesitará utilizar el método PrivateFontCollection.AddMemoryFont(). Por ejemplo, he añadido un archivo de fuentes llamado "test.ttf" como un recurso y lo utilizó como esto:

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

tenga en cuenta que la variable estática fontBuffer es intencionadamente. La administración de la memoria es difícil cuando se usa AddMemoryFont(), la memoria debe permanecer válida siempre que la fuente se pueda utilizar y PrivateFontCollection aún no se elimine. Asegúrese de no llamar a Marshal.FreeCoTaskMem() si no tiene esa garantía, se trata de un muy error común que causa un daño de texto muy difícil de diagnosticar. Solo tienes una AccessViolationException cuando tienes suerte. Mantenerlo válido durante la vida del programa es la solución simple.

+0

Excelente. Gracias por publicar. – Harsha

+1

@HansPassant: ¿y si el archivo de fuente que quiero agregar tiene la extensión '.bin' en lugar de '.ttf' –

+1

Necesitaba usar PInvoke antes de que las cosas funcionaran. La función ['AddFontMemResourceEx'] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183325 (v = vs.85) .aspx) tuvo que ser utilizada ... quizás porque' PrivateFontCollection .AddMemoryFont() 'espera que la fuente esté en la memoria del sistema. También me pregunto si esto tiene algo que ver con el hecho de que estaba cambiando la fuente de un cuadro de texto, en lugar de hacerlo de forma explícita con la fuente. (Sin embargo, el uso de 'PrivateFontCollection.AddFontFile()' todavía funcionaba sin la función PInvoke). –

Cuestiones relacionadas