top of page

Get a list of all Fonts installed on a device using the EnumFontFamiliesEx Windows API Function

  • Writer: John
    John
  • 6 minutes ago
  • 3 min read
This post is one of a series providing implementation examples of Windows API Functions, Types, Enums and Consts using VBA. The code in this post can be used as-is, however, if you regularly (or even just occasionally) work with Windows API declarations in VBA, you may want to see the posts Automatically add Windows API declaration(s) and Using 'F1' to view Windows API web pages which explain some of the functionality that can be added to the VBE by VBE_Extras.

The EnumFontFamiliesEx Windows API Function enumerates all uniquely-named fonts (or font / character set combinations) on a device.


To do this:


  • A device context is required, obtained using the GetDC Windows API Function (the device context must also be released once it is finished with in order to avoid memory leaks ... this is done using the ReleaseDC Windows API Function)

  • A LOGFONT Type is required with its lfCharSet and lfFaceName members set to specific values if required in order to control which fonts are enumerated (see the 'Remarks' section of the LOGFONT documentation for details). In the case of the demo VBA code, below, we set the lfCharSet member to DEFAULT_CHARSET if we want to enumerate all font / character set combinations (on my device, this results in 1,138 individual font / character set combinations being found) ... we leave lfCharSet at its default value if we only want to enumerate the fonts (on my device, this results in 288 individual fonts being found).

  • A VBA 'callback' Function is required that will be called repeatedly, once for each font (or font / character set combination) ... this Function must have a specific set of parameters ... it is these parameters that will contain information on each font


Note that the lfCharSet member of the LOGFONT can be set to a specific character set value in order to only enumerate the fonts that support that character set. For example, to see all fonts that support a 'symbol' character set, you would set lfCharSet to 2 (the value for the SYMBOL_CHARSET constant) before the call of EnumFontFamiliesEx (on my device, this results in 10 individual fonts being found) ... or to see all fonts that support a Greek character set, you would set lfCharSet to 161 (the value for the GREEK_CHARSET constant) before the call of EnumFontFamiliesEx (on my device, this results in 158 individual fonts being found). You can see the names of all of the available *CHARSET constants in the documentation for the LOGFONT Type ... but the documentation doesn't include the numeric value associated with each constant. If you want to get those values, the easiest way is to use the Automatically add Windows API declaration(s) functionality of VBE_Extras.


So, once EnumFontFamiliesEx is called (once) from your VBA code, the VBA 'callback' Function that receives the information on each font will be (repeatedly) called, once for each font. It's then just a case of getting the information you want from the parameters. In the case of the example code, below, we get:


  • The font family name (e.g. "Arial", "Times New Roman", "Verdana") from the elfFullName member of the ENUMLOGFONTEX Type that is passed in as the lpelfe parameter

  • The font style (e.g. "Regular", "Semibold", "Light") from the elfStyle member of the same ENUMLOGFONTEX Type

  • The font script (e.g. "Western", "Symbol", "Greek") from the elfScript member of the same ENUMLOGFONTEX Type

  • The font type (a numeric value, either RASTER_FONTTYPE, DEVICE_FONTTYPE or TRUETYPE_FONTTYPE) from the FontType parameter


... there is much more information passed in to the Function that you can experiment with if you wish.


So this is the code. The UpdateFontFamilyNames Function prepares 4 arrays (one for each of the above types of information i.e. the 4 bullets, above), declares a LOGFONT (and sets its lfCharSet member if required), gets a device context then calls EnumFontFamiliesEx. Once the arrays are populated with the font details, it releases the device context then ensures the 4 arrays are dimensioned correctly.


EnumFontFamExProc is the 'callback' Function that is called repeatedly and handles populating the arrays with the information about each font (or font / character set combination). There's a couple of supporting Functions to trim each String and get a text equivalent for each 'font family type'.



This 'runnable' Sub brings it all together. It calls the code to get all of the fonts (change the False to True in the call of UpdateFontFamilyNames to get all font / character set combinations instead of all fonts) and then logs details to the Immediate window. Obviously this could be adjusted to populate a ComboBox or ListBox in order to have the user select a specific font (or font / character set combination).





bottom of page