title: Embed custom font fot text box use in Visual Basic 2010
body: <p>OK I'm working on a problem tyring to embed a LCD type true type font in a text box. As for some background, I can get the lcd font to display if I install the font onto my system, then load it as the font type for the text box and it works great. However, it will not work as an embedded font in the application. I"m using a a Windows Forms Application in Visual Basic, from the Microsoft Visual Studio 2010 on a Windows 7 box. </p>
  
  <p>I have tried the following code using a private font collection from memory after storing the font as a resource file and setting the property to embed resource.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The problem with this code is that you are supposed to enable the control's UseCompatibleTextRendering property to true. Granted if using this module on a lable or button text it works great. For a text box however, there is no UseCompatibleTextRendering property.</p>
  
  <p>I've come to understand that the text boxes use GDI rendering whereas the other text controls use GDI+ ( I may have those switched around, so don't quote me on that, All i remember is that they are different).</p>
  
  <p>I found some older code snipits trying that use the AddFontMemResourceEX function from the gdi32.dll file in windows, and some have claimed that it works for use in text boxes. So I created the following class.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>However when calling this class, I get a InvalidOperatioException was unhandled. The error is Unable to find an entry pointed named 'AddFontMemResourceEX in DLL 'gdi32.dll'.</p>
  
  <p>Hoping someone could help me either tell me what i'm going wrong, or point me in a direction that would help me embed a font for use in text boxes for use with a Windows Forms Application. </p>
  
  <p>Most of the examples referenced at MSDN all point to how to package fonts when using a WPF application.</p>
  
  <p>Thank you.</p>