Embedding Fonts into Windows Forms
When it comes to fonts, most Windows Forms applications can get by using the default ones installed onto the user’s system. Generally, this means Microsoft Sans Serif, Ariel, Courier New or even Verdana. However, there may be some scenarios where an application requires a custom font that isn’t likely available on the user’s system – and installation isn’t an option.
Download Example
- Visual Studio 2005 Project (ZIP File: 33,789 bytes)
- Example Binary (ZIP File: 19,414 bytes)
Refresher: Resources
You can embed just about anything into an application’s resource area, and fonts are no exception. Once added, the resources are readily accessible (read-only) from the application’s strongly-typed Properties.Resource class generated for you by the compiler. The resource class nativity supports strings, images, icons, audio, files and any other binary data (like fonts) and will allow you to access it through .NET’s System.Drawing.Bitmap, System.String, System.IO.Stream and System.Byte[] types. You can read more about adding and editing resources on MSDN from here.
Since .NET does not make the connection between a font file and System.Drawing.Font object for you, there is a bit of work required so that we can turn the resources into a usable font.
System.Drawing.Font
In .NET 2.0, the System.Drawing.Font object has 13 different constructors. You will very quickly realize that none of them accept a file path or a byte array of a font file (which is what we currently have from the resources class). Upon closer inspection of the Font class, you will also realize some static functions allowing you to create a font instance from a device context, Windows handle or from a Logical GDI structure – all of which is of no use to us.
The problem is that the Font class can only access fonts which have been “installed” on the user’s system. This means that Windows needs to have the font registered internally for it to be accessible to applications. What we need to do is to get our font, in the application resources, temporarily “registered” with Windows. Luckily, Windows has a Win32 function (in gdi32.dll) called AddFontMemResourceEx which allows us to do just that.
Registering the Font
Since .NET does not natively have the functions we need to call, we’re going to need to import them from the gdi32 DLL by using P/Invoke. We’re going to be using AddFontResourceEx to register the font, and then RemoveFontMemResourceEx when we’re ready to clean up (discussed later).
using System.Runtime.InteropServices; ... [DllImport("gdi32")] private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); [DllImport("gdi32")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool RemoveFontMemResourceEx(IntPtr fh);
In our Windows Forms application, the best place to initialize the custom font(s) is from the class constructor of the main form used in the application. From here, we’re going to need to do a couple of things:
- Create a new System.Drawing.Text.PrivateFontCollection instance which will store our dynamically-loaded font(s).
- Tell the garbage collector to pin down the font’s binary data in memory so Windows can access it from outside our .NET managed bubble.
- Add the font handle to our private font collection (in memory).
- Register the font with Windows using the AddFontMemResourceEx function call.
The following code demonstrates the above description:
using System.Drawing; using System.Drawing.Text; ... /* Member Variables */ private PrivateFontCollection m_PFC; private GCHandle m_pFont; private IntPtr m_hFont; ... // Somewhere called from the form constructor... m_PFC = new PrivateFontCollection(); int rsxLen = Properties.Resources.ClientFont.Length; m_pFont = GCHandle.Alloc(Properties.Resources.MyFont, GCHandleType.Pinned); m_PFC.AddMemoryFont(m_pFont.AddrOfPinnedObject(), rsxLen); uint rsxCnt = 1; /* We're only installing one font. */ // This is where we do the actual "registration" to get the font handle m_hFont = AddFontMemResourceEx(m_pFont.AddrOfPinnedObject(), (uint)rsxLen, IntPtr.Zero, ref rsxCnt);
In this example, we’re just going to register a single font called MyFont from the application resources class. To add multiple fonts, we would just need to create a font handle to each font we wish to add, create a pinned GC handle to it, add it to the private font collection and register it using AddFontMemResourceEx. Lather, rinse, repeat.
Creating the Font
Now that Windows knows about our custom font, all we have to do now is create a System.Drawing.Font instance of it so we can use it in our form controls (and whatever else). The private font collection allows us to iterate over all the System.Drawing.FontFamily objects available from the font(s) we’ve added. It is important to note that since not all fonts support all font styles (Regular, Bold, Italic, etc), we have to make sure the font we’re going to create supports the style we wish to use – otherwise, we’ll end up with a default fallback font.
The following code demonstrates how we can create a font we registered from the previous example:
... /* Member Variables */ private Font m_Font; ... FontFamily ff = m_PFC.Families[0]; /* I know, bad practice. */ if (ff.IsStyleAvailable(FontStyle.Regular)) { m_Font = new Font(ff, 7f, FontStyle.Regular, GraphicsUnit.Point); } else { // ...cry... }
Now that we have an instance of System.Drawing.Font, we can pass this into any control and presto-chango, our font should show up:

Clean Up
Before the application exits, it is important to properly dispose of any unmanaged handles we were using. Remember the RemoveFontMemResourceEx function mentioned earlier? This is where will will be using it. The following example demonstrates the very simple clean-up process:
protected override void Dispose(bool disposing) { #region Release Managed if (disposing && (components != null)) { components.Dispose(); } #endregion #region Release Unmanaged m_PFC.Dispose(); m_pFont.Free(); RemoveFontMemResourceEx(m_hFont); #endregion base.Dispose(disposing); }
First we dispose of all the managed components (as usual) and then we clean up the objects we allocated for the font(s). We just dispose of the private font collection, the GC handle to the font data and finally remove the font handle from memory (unregistration). Not much to it at all.
Credits
Barcode Font: Anke Arnold – www.anke-art.de