10

Windows フォーム アプリケーションに埋め込みリソースとしてフォントを埋め込み、TextBox.

のヘルプにAddMemoryFont()よると、GDI+ を使用するには、互換性のあるテキスト レンダリングを に設定する必要trueがあるため、フォントを使用できます。しかし、どういうわけか、正しいフォントが表示されません。

Program.cs では、次のように明示的に述べています。

Application.SetCompatibleTextRenderingDefault(true);

では、なぜ機能しないのでしょうか。カスタム フォントを TextBox に設定する方法を知っている人はいますか?

4

2 に答える 2

29

インターウェブと Google のおかげでわかりました。

今後の参考のために、誰かがこの問題を抱えている場合の修正は次のとおりです。埋め込みフォントをストリームとして取得した後、 AddMemoryFont を呼び出す前に、 AddFontMemResourceEx を呼び出す必要があります。(C# では使用できないため、インポートする必要があります。

    [DllImport("gdi32.dll")]
    private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);

その後 :

            //create an unsafe memory block for the data
        System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);
        //create a buffer to read in to
        Byte[] fontData = new Byte[fontStream.Length];
        //fetch the font program 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);

        // We HAVE to do this to register the font to the system (Weird .NET bug !)
        uint cFonts = 0;
        AddFontMemResourceEx(data, (uint)fontData.Length, IntPtr.Zero, ref cFonts);

        //pass the font to the font collection
        mFontCollection.AddMemoryFont(data, (int)fontStream.Length);
        //close the resource stream
        fontStream.Close();
        //free the unsafe memory
        Marshal.FreeCoTaskMem(data);

さきほど、フォントを使用できるようになります。AddFontMemResourceEx がないと機能しません。

于 2009-12-24T00:10:21.520 に答える
2

おかげで動作しています。C# Windows アプリケーションにフォントを埋め込むには

[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);

    PrivateFontCollection pFC = new PrivateFontCollection();

        try
        {
            string[] resource = { "newFont-Bold.ttf", "newFont-Regular.ttf" }; // specify embedded resource name

            foreach (var item in resource)
            {
                // receive resource stream
                Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(item);

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

                ///IMPORTANT line to register font in system
                uint cFonts = 0;
                AddFontMemResourceEx(data, (uint)fontdata.Length, IntPtr.Zero, ref cFonts);

                // pass the font to the font collection
                pFC.AddMemoryFont(data, (int)fontStream.Length);

                // close the resource stream
                fontStream.Close();
                // free up the unsafe memory
                Marshal.FreeCoTaskMem(data);
            }
        }
        catch (Exception exp)
        {
            Log.Error(exp);
        }

        return pFC;
于 2020-01-07T04:39:43.540 に答える