How do I get all installed fixed-width fonts?

后端 未结 3 2013
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-05 11:33

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 acce

相关标签:
3条回答
  • 2020-12-05 11:40

    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.

    0 讨论(0)
  • 2020-12-05 11:46

    Unfortunately ToLogFont function does not fill lfPitchAndFamily field to correct values. In my case it's always 0.

    One approximation to detect which fonts might be fixed is the following

        foreach ( FontFamily ff in FontFamily.Families ) {
                if ( ff.IsStyleAvailable( FontStyle.Regular ) ) {
                    float diff;
                    using ( Font font = new Font( ff, 16 ) ) {
                        diff = TextRenderer.MeasureText( "WWW", font ).Width - TextRenderer.MeasureText( "...", font ).Width;
                    }
                    if ( Math.Abs( diff ) < float.Epsilon * 2 ) {
                        Debug.WriteLine( ff.ToString() );
                    }
                }
    
            }
    

    Keep in mind that they are several false positives, for example Wingdings

    0 讨论(0)
  • 2020-12-05 11:59

    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......
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题