簡體   English   中英

如何將privatefontcollection內存中的字體呈現為可編輯的控件

[英]How to render a font from privatefontcollection memory to editable controls

這是將資源從資源加載到PrivateFontCollection導致損壞的延續

這里提供的答案足以用於具有UseCompatibleTextRendering方法的控件,但是它似乎不適用於其他常見控件,其中文本是主要焦點,例如:

  • 列表顯示
  • 文本框
  • RichTextBox的
  • 組合框
  • ... 還有很多...

我已經嘗試過這里的信息,這些信息基本上是用Program.csApplication.SetCompatibleTextRenderingDefault行進行的(沒有人明白這個設置是默認的,所以我在這里記錄它)。 我也玩過Telerik,DevExpress和Infragistics文本控件,除了Telerik之外沒有內置兼容文本渲染的能力.Teleriks控件有這個方法,但它沒有效果,包括無法將forecolor設置為存儲的內容在屬性(一個不同的動物,只是注意到Telerik radTextBox控件的毛刺)。

似乎無論我如何切片,任何對文本實際有用的控件都不會使文本正確顯示正方形字符,如上面提到的原始帖子所示。

綜上所述 :

  • 字體從資源加載到內存到PrivateFontCollection
  • 應用程序不會崩潰
  • 成功在標簽上使用相同的字體(UseCompatibleTextRendering對它們起作用) - 在同一個表單上,在同一個項目中。

  • 受此(新?)問題影響的控件嚴格來說是任何可以“鍵入”的控件,如TextEdit,ListView,RichText,Combo等。

  • 當談到切換,玩弄或玩耍時 - 這意味着我已經嘗試了所提供的所有控件和/或代碼的所有可能組合。 例如: Application.SetCompatibleTextRenderingDefault本身只有3種可能的組合。 (true) (false)或完全省略。 在完成這3個組合之后,我接着進行了(基本故障排除,但我發現有必要解釋所有基礎)添加Telerik控件,然后嘗試Telerik控件中的所有組合,以及Application.SetCompatibleTextRenderingDefault所有組合Application.SetCompatibleTextRenderingDefault命令。 測試的數量是指數級的,即渲染可能性的可能組合的數量乘以嘗試的控制的數量乘以每個控件具有的渲染控制的可能性的數量,等等。

經過大量的挖掘,並在此問題上空洞了(包括仍然困擾我的這個問題的驅動器),我已經找到了解決這個問題的解決方案,它似乎已經面臨許多問題並且也出現了問題 - 只需將字體作為文件安裝在用戶系統上即可。 正如我想的那樣,這根本不是必需的,你可以用一種簡單的方式嵌入字體,這樣就可以在任何控件上使用它,包括TextBox,ComboBox等。無論你的內心需要什么。

我將把它作為一步一步的指南來編寫,如何將字體嵌入到項目中並使其在您想要的任何控件上正確顯示。

第1步 - 選擇受害者(字體選擇)

出於演示目的(和流行的需求),我將使用FontAwesome字體(在撰寫本文時為v 4.1)

  • 在項目內,轉到Project > <your project name> Properties
  • 單擊“ Resources (應位於左側)
  • 單擊“ Add Resource按鈕右側的下拉箭頭,然后選擇“ Add Existing File

在此輸入圖像描述

  • 確保從下拉列表中選擇All Files (*.*) ,然后瀏覽到要嵌入的字體文件的位置,選擇它,然后單擊[打開]按鈕。 在此輸入圖像描述

您現在應該看到如下內容: 在此輸入圖像描述

  • 按[CTRL] + [S]保存項目。

第2步 - 潛入代碼

復制以下代碼並將其另存為“MemoryFonts.cs”,然后將其添加到項目中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;
using System.Drawing.Text;
using System.Drawing;

public static class MemoryFonts {

    [DllImport( "gdi32.dll" )]
    private static extern IntPtr AddFontMemResourceEx( IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts );
    private static PrivateFontCollection pfc { get; set; }

    static MemoryFonts() {
        if ( pfc==null ) { pfc=new PrivateFontCollection(); }
    }

    public static void AddMemoryFont(byte[] fontResource) {
        IntPtr p;
        uint c = 0;

        p=Marshal.AllocCoTaskMem( fontResource.Length );
        Marshal.Copy( fontResource, 0, p, fontResource.Length );
        AddFontMemResourceEx( p, (uint)fontResource.Length, IntPtr.Zero, ref c );
        pfc.AddMemoryFont( p, fontResource.Length );
        Marshal.FreeCoTaskMem( p );

        p = IntPtr.Zero;
    }

    public static Font GetFont( int fontIndex, float fontSize = 20, FontStyle fontStyle = FontStyle.Regular ) {
        return new Font(pfc.Families[fontIndex], fontSize, fontStyle);
    }

    // Useful method for passing a 4 digit hex string to return the unicode character
    // Some fonts like FontAwesome require this conversion in order to access the characters
    public static string UnicodeToChar( string hex ) {
        int code=int.Parse( hex, System.Globalization.NumberStyles.HexNumber );
        string unicodeString=char.ConvertFromUtf32( code );
        return unicodeString;
    }

}

第3步 - 使它漂亮(使用字體)

  • 在主窗體上,從工具箱中添加TextBox控件 在此輸入圖像描述

  • form_Load事件中,放入以下代碼(在我的情況下,資源是fontawesome_webfont 。將其更改為您命名的字體資源)

     private void Form1_Load( object sender, EventArgs e ) { MemoryFonts.AddMemoryFont( Properties.Resources.fontawesome_webfont ); textBox1.Font = MemoryFonts.GetFont( // using 0 since this is the first font in the collection 0, // this is the size of the font 20, // the font style if any. Bold / Italic / etc FontStyle.Regular ); // since I am using FontAwesome, I would like to display one of the icons // the icon I chose is the Automobile (fa-automobile). Looking up the unicode // value using the cheat sheet https://fortawesome.github.io/Font-Awesome/cheatsheet/ // shows : fa-automobile (alias) [&#xf1b9;] // so I pass 'f1b9' to my UnicodeToChar method which returns the Automobile icon textBox1.Text = MemoryFonts.UnicodeToChar( "f1b9" ); } 

最終的結果

在此輸入圖像描述


您可能會或可能不會注意到我制作此方法時請記住您可能希望添加多個嵌入字體。 在這種情況下,您只需為要添加的每個字體調用AddMemoryFont() ,然后在使用GetFont()時使用適當的索引值(基於零GetFont()

與Microsoft的UseCompatibleTextRendering ()文檔相關的文檔相反,您UseCompatibleTextRendering SetCompatibleTextRenderingDefault使用UseCompatibleTextRenderingSetCompatibleTextRenderingDefault 上面概述的方法允許在對象/控件中自然呈現字體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM