OK 私は LCD タイプの True Type フォントをテキスト ボックスに埋め込む問題に取り組んでいます。いくつかの背景については、システムにフォントをインストールし、それをテキスト ボックスのフォント タイプとしてロードすると、lcd フォントを表示することができ、うまく機能します。ただし、アプリケーションの埋め込みフォントとしては機能しません。Windows 7 ボックスの Microsoft Visual Studio 2010 から、Visual Basic で Windows フォーム アプリケーションを使用しています。
フォントをリソース ファイルとして保存し、リソースを埋め込むようにプロパティを設定した後、メモリからプライベート フォント コレクションを使用して次のコードを試しました。
Imports System.Drawing.Text
Imports System.Runtime.InteropServices
Module CustomFont
'PRIVATE FONT COLLECTION TO HOLD THE DYNAMIC FONT
Private _pfc As PrivateFontCollection = Nothing
Public ReadOnly Property GetInstance(ByVal Size As Single, _
ByVal style As FontStyle) As Font
Get
'IF THIS IS THE FIRST TIME GETTING AN INSTANCE
'LOAD THE FONT FROM RESOURCES
If _pfc Is Nothing Then LoadFont()
'RETURN A NEW FONT OBJECT BASED ON THE SIZE AND STYLE PASSED IN
Return New Font(_pfc.Families(0), Size, style)
End Get
End Property
Private Sub LoadFont()
Try
'INIT THE FONT COLLECTION
_pfc = New PrivateFontCollection
'LOAD MEMORY POINTER FOR FONT RESOURCE
Dim fontMemPointer As IntPtr = _
Marshal.AllocCoTaskMem( _
My.Resources.DIGITALDREAMNARROW.Length)
'COPY THE DATA TO THE MEMORY LOCATION
Marshal.Copy(My.Resources.DIGITALDREAMNARROW, _
0, fontMemPointer, _
My.Resources.DIGITALDREAMNARROW.Length)
'LOAD THE MEMORY FONT INTO THE PRIVATE FONT COLLECTION
_pfc.AddMemoryFont(fontMemPointer, _
My.Resources.DIGITALDREAMNARROW.Length)
'FREE UNSAFE MEMORY
Marshal.FreeCoTaskMem(fontMemPointer)
Catch ex As Exception
'ERROR LOADING FONT. HANDLE EXCEPTION HERE
End Try
End Sub
End Module
このコードの問題は、コントロールの UseCompatibleTextRendering プロパティを true に設定する必要があることです。このモジュールをラベルまたはボタンのテキストで使用すると、うまく機能します。ただし、テキスト ボックスの場合、UseCompatibleTextRendering プロパティはありません。
テキスト ボックスは GDI レンダリングを使用するのに対し、他のテキスト コントロールは GDI+ を使用することを理解するようになりました (それらを切り替えている可能性があるため、引用しないでください。覚えているのは、それらが異なることだけです)。
Windows で gdi32.dll ファイルの AddFontMemResourceEX 関数を使用しようとしている古いコード スニピットをいくつか見つけました。テキスト ボックスでの使用に適していると主張する人もいます。そこで、次のクラスを作成しました。
Imports System
Imports System.Drawing.Text
Imports System.IO
Imports System.Reflection
Public Class GetLCDFont
Private Declare Auto Function AddFontMemResourceEX Lib "gdi32.dll" _
(ByVal pbFont As Integer, ByVal cbFont As Integer, _
ByVal pdv As Integer, ByRef pcFonts As Integer) As IntPtr
Public Shared Function GetFont(ByVal fontName As String) As FontFamily
Dim exeCurrent As [Assembly] = [Assembly].GetExecutingAssembly()
Dim nameSpc As String = exeCurrent.GetName().Name.ToString()
Dim fontCollection As New PrivateFontCollection
Dim loadStream As Stream = exeCurrent.GetManifestResourceStream( _
nameSpc + "." + fontName)
Dim byteBuffer(CType(loadStream.Length, Integer)) As Byte
loadStream.Read(byteBuffer, 0, Int(CType(loadStream.Length, Integer)))
Dim fontPtr As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal( _
Runtime.InteropServices.Marshal.SizeOf(GetType(Byte)) * _
byteBuffer.Length)
Runtime.InteropServices.Marshal.Copy(byteBuffer, 0, fontPtr, byteBuffer.Length)
fontCollection.AddMemoryFont(fontPtr, byteBuffer.Length)
Dim pcFonts As Int32 = 1
AddFontMemResourceEX(fontPtr, byteBuffer.Length, 0, pcFonts)
Runtime.InteropServices.Marshal.FreeHGlobal(fontPtr)
Return fontCollection.Families(0)
End Function
Public Sub New()
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
ただし、このクラスを呼び出すと、InvalidOperatioException が処理されませんでした。エラーは、DLL 'gdi32.dll' で 'AddFontMemResourceEX' という名前のエントリが見つかりません。
誰かが私が間違っていることを教えてくれるか、Windowsフォームアプリケーションで使用するテキストボックスで使用するフォントを埋め込むのに役立つ方向を教えてくれることを願っています.
MSDN で参照されているほとんどの例はすべて、WPF アプリケーションを使用するときにフォントをパッケージ化する方法を示しています。
ありがとうございました。