tags:

views:

1558

answers:

3

I'm wondering if there are any simple ways to get a list of all fixed-width (monospaced) fonts installed on a user's system in C#?

I'm using .net 3.5 so have access to the WPF System.Windows.Media namespace and LINQ to get font information, but I'm not sure what I'm looking for.

I want to be able to provide a filtered list of monospaced fonts and/or pick out monospaced fonts from a larger list of fonts (as seen in the VS options dialog).

A: 

AFAIK you can't do it using BCL libraries only. You have to use WinAPI interop.

You need to analyze 2 lowest bits of LOGFONT.lfPitchAndFamily member. There is a constant FIXED_PITCH (means that font is fixed-width) that can be used as a bit mask for lfPitchAndFamily.

Here is a useful article:

Enumerating Fonts

Enumerating fonts can be a little confusing, and unless you want to enumerate all fonts on your system, can be a little more difficult than MSDN suggests. This article will explain exactly the steps you need to use to find every fixed-width font on your system, and also enumerate every possible size for each individual font.

aku
A: 

You can use the InstalledFontCollection class.

   using System.Drawing.Text;
   using System.Drawing;
   ...
   InstalledFontCollection fc = new InstalledFontCollection();
   foreach (FontFamily MyFontFamily in fc.Families)
   {
       Console.WriteLine("Family name {0}", MyFontFamily.Name);
   }

Sorry, locating the GenericFontFamilies.Monospace property in a family, is still to be researched.

gimel
+3  A: 

Have a look at:

http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html

Use one of the structures in there, then loop over families, instantiating a Font, and getting the LogFont value and checking lfPitchAndFamily.

The following code is written on the fly and untested, but something like the following should work:

foreach (FontFamily ff in System.Drawing.FontFamily.Families)
{
    if (ff.IsStyleAvailable(FontStyle.Regular))
    {
        Font font = new Font(ff, 10);
        LOGFONT lf = new LOGFONT();
        font.ToLogFont(lf);
        if (lf.lfPitchAndFamily ^ 1)
        {
            do stuff here......
        }
    }
}
Tim