2010-05-28 17 views
7

Làm thế nào để sử dụng phông chữ tài nguyên trực tiếp mà không lưu phông chữ trong hệ thống tệp cục bộ cho ứng dụng độc lập [ứng dụng dành cho máy tính để bàn] trong VB.net/C#?Sử dụng phông chữ tài nguyên trực tiếp trong VB.net/C#

+0

@SamSol: không có điều gì như CS.NET. Bạn đã từng nghe về điều đó ở đâu? Ngôn ngữ chỉ là "C#". –

Trả lời

14

Có thể, bạn sẽ cần sử dụng phương thức PrivateFontCollection.AddMemoryFont(). Ví dụ, tôi đã thêm một tập tin phông chữ có tên là "test.ttf" như một nguồn tài nguyên và sử dụng nó như thế này:

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

Do lưu ý rằng biến fontBuffertĩnh cố ý. Quản lý bộ nhớ rất khó khi bạn sử dụng AddMemoryFont(), bộ nhớ cần duy trì hợp lệ miễn là phông chữ có thể được sử dụng và PrivateFontCollection chưa được xử lý. Hãy chắc chắn không gọi Marshal.FreeCoTaskMem() nếu bạn không có bảo đảm đó, đó là một lỗi phổ biến gây ra rất khó chẩn đoán tham nhũng văn bản là rất. Bạn chỉ nhận được AccessViolationException khi bạn may mắn. Giữ nó hợp lệ cho cuộc đời của chương trình là giải pháp đơn giản.

+0

Tuyệt vời. Cảm ơn vì đăng. – Harsha

+1

@ HansPassant: nếu tệp phông chữ tôi muốn thêm có phần mở rộng '.bin' thay vì '.ttf' –

+1

tôi cần sử dụng PInvoke trước khi mọi thứ hoạt động. Hàm ['AddFontMemResourceEx'] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183325 (v = vs.85) .aspx) phải được sử dụng ... có lẽ vì' PrivateFontCollection .AddMemoryFont() 'mong đợi phông chữ nằm trong bộ nhớ hệ thống. Tôi cũng tự hỏi liệu điều này có liên quan gì đến thực tế là tôi đã thay đổi phông chữ của một hộp văn bản, chứ không phải là hiển thị rõ ràng với phông chữ. (Tuy nhiên, sử dụng 'PrivateFontCollection.AddFontFile()' vẫn hoạt động mà không có hàm PInvoke). –

Các vấn đề liên quan