VB.NET Tips / Tricks / Examples and Help

VB.NET Include a font as an embedded resource in your application

 Today I am going to show you how you can take a font file, and include it in your VB.NET WinForms application. This means you can load the font at runtime, and use it on your controls without requiring the user to have the font installed on their system. This can come in handy when you want to use a custom font, but your app needs to run without admin rights (because of ClickOnce or other least privileged requirements). Without admin rights you cannot install fonts on a system. (Note: I have seen some workarounds to this, but they require 3rd party utilities).

This is a pretty simple example, and there is not a ton of code. So lets get right down to it:

First lets see the end result.

Here is what the form looks like when I run it normally

Here is what the form looks like when I click the button and load the custom font (which happens to be a digital clock looking font)

 

The code to do this? Let's take a look. I created a new Windows Forms application, and added a ttf (true type font) file to the resources section of my project. It will be stored under the "files" section of the resources, which means accessing this font in code from the resources will just return a byte array of the file.

I created a module and put all the code needed to load the custom font in there. That way you can make quick calls to it to setup the custom font on your controls.

'MATTHEW KLEINWAKS

'ZerosAndTheOne.com

'2009

'CUSTOM FONT LOADED DYNAMICALLY FROM A RESOURCE

 

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

It is pretty straight forward, and the code has comments so you can see what is going on.

Then in the form, when the button is clicked, we make a single call to the module's GetInstance method to return the font.

    Private Sub Button1_Click(ByVal sender As System.Object, _

                              ByVal e As System.EventArgs) _

                              Handles Button1.Click

 

        Label1.Font = CustomFont.GetInstance(12, FontStyle.Bold)

 

    End Sub

IMPORTANT: One key thing to note here, is that on the control you want to set this custom font on, you will need to set the UseCompatibleTextRendering property to true (the default is false). If you don't want to do this for some reason, then another method you can do is to use the given controls Paint event and custom draw the text using the custom font. However this is generally less ideal because not all controls fire paint events without tweaking them, and even some that do would put the burden on drawing the entire control in your hands. So setting UseCompatibleTextRendering to true is the easier route to go.

That is all there is to it. You can modify this to meet the specific needs of your application. Below is a link to download the WinForms application (VS2008) that contains the code (and font) used in this article.

 


Posted Nov 20 2009, 06:05 AM by Matthew Kleinwaks


© 2014 - ZerosAndTheOne.com - Hosting by Orcsweb (http://www.orcsweb.com/)
Powered by Community Server (Non-Commercial Edition), by Telligent Systems