My ultimate goal is to list all active fonts on a Windows computer. For example, if you run WordPad or Word, you will see all of them. Some of these fonts come from the windows \ fonts folder, but not for everyone. Some of them are dynamically registered by calling gdi32.dll AddFontResource (...). Now you would think that C # had support for retrieving the whole list, and if so, let me know please!
However, after spending many hours doing this, regular C # calls to install installed system fonts retrieve only some of all existing fonts. For example, InstalledFontCollection.Families does not find any of the fonts added using AddFontResource (it finds about 25% of the fonts listed in the text box!)
While I want to do this in C #, it seems I need to use some more calls to gdi32.dll. So my problem began with EnumFontFamiliesEx.
I managed to get the following code that works to such an extent that I get a bunch of callbacks with fonts. However, the ENUMLOGFONTEX structure seems to be corrupted, and for example, lpelfe.elfFullName usually contains a pair of square characters, rather than a real name. Perhaps I was mistaken in sorting or defining the structure, not quite sure. I tried a lot of iterations and an endless google search, but to no avail.
Any help would be greatly appreciated.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Media; using System.Runtime.InteropServices; using Microsoft.Win32; namespace FontRetriever { public partial class TestForm : Form { [DllImport("gdi32.dll")] static extern int EnumFontFamiliesEx(IntPtr hdc, [In] IntPtr pLogfont, EnumFontExDelegate lpEnumFontFamExProc, IntPtr lParam, uint dwFlags); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class LOGFONT { public int lfHeight; public int lfWidth; public int lfEscapement; public int lfOrientation; public FontWeight lfWeight; [MarshalAs(UnmanagedType.U1)] public bool lfItalic; [MarshalAs(UnmanagedType.U1)] public bool lfUnderline; [MarshalAs(UnmanagedType.U1)] public bool lfStrikeOut; public FontCharSet lfCharSet; public FontPrecision lfOutPrecision; public FontClipPrecision lfClipPrecision; public FontQuality lfQuality; public FontPitchAndFamily lfPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string lfFaceName; } public enum FontWeight : int { FW_DONTCARE = 0, FW_THIN = 100, FW_EXTRALIGHT = 200, FW_LIGHT = 300, FW_NORMAL = 400, FW_MEDIUM = 500, FW_SEMIBOLD = 600, FW_BOLD = 700, FW_EXTRABOLD = 800, FW_HEAVY = 900, } public enum FontCharSet : byte { ANSI_CHARSET = 0, DEFAULT_CHARSET = 1, SYMBOL_CHARSET = 2, SHIFTJIS_CHARSET = 128, HANGEUL_CHARSET = 129, HANGUL_CHARSET = 129, GB2312_CHARSET = 134, CHINESEBIG5_CHARSET = 136, OEM_CHARSET = 255, JOHAB_CHARSET = 130, HEBREW_CHARSET = 177, ARABIC_CHARSET = 178, GREEK_CHARSET = 161, TURKISH_CHARSET = 162, VIETNAMESE_CHARSET = 163, THAI_CHARSET = 222, EASTEUROPE_CHARSET = 238, RUSSIAN_CHARSET = 204, MAC_CHARSET = 77, BALTIC_CHARSET = 186, } public enum FontPrecision : byte { OUT_DEFAULT_PRECIS = 0, OUT_STRING_PRECIS = 1, OUT_CHARACTER_PRECIS = 2, OUT_STROKE_PRECIS = 3, OUT_TT_PRECIS = 4, OUT_DEVICE_PRECIS = 5, OUT_RASTER_PRECIS = 6, OUT_TT_ONLY_PRECIS = 7, OUT_OUTLINE_PRECIS = 8, OUT_SCREEN_OUTLINE_PRECIS = 9, OUT_PS_ONLY_PRECIS = 10, } public enum FontClipPrecision : byte { CLIP_DEFAULT_PRECIS = 0, CLIP_CHARACTER_PRECIS = 1, CLIP_STROKE_PRECIS = 2, CLIP_MASK = 0xf, CLIP_LH_ANGLES = (1 << 4), CLIP_TT_ALWAYS = (2 << 4), CLIP_DFA_DISABLE = (4 << 4), CLIP_EMBEDDED = (8 << 4), } public enum FontQuality : byte { DEFAULT_QUALITY = 0, DRAFT_QUALITY = 1, PROOF_QUALITY = 2, NONANTIALIASED_QUALITY = 3, ANTIALIASED_QUALITY = 4, CLEARTYPE_QUALITY = 5, CLEARTYPE_NATURAL_QUALITY = 6, } [Flags] public enum FontPitchAndFamily : byte { DEFAULT_PITCH = 0, FIXED_PITCH = 1, VARIABLE_PITCH = 2, FF_DONTCARE = (0 << 4), FF_ROMAN = (1 << 4), FF_SWISS = (2 << 4), FF_MODERN = (3 << 4), FF_SCRIPT = (4 << 4), FF_DECORATIVE = (5 << 4), } [StructLayout(LayoutKind.Sequential)] public class NEWTEXTMETRICEX {
}