18

我想知道是否有任何简单的方法可以在 C# 中获取用户系统上安装的所有固定宽度(等宽)字体的列表?

我正在使用 .net 3.5,因此可以访问 WPF System.Windows.Media 命名空间和 LINQ 以获取字体信息,但我不确定我在寻找什么。

我希望能够提供过滤的等宽字体列表和/或从更大的字体列表中挑选等宽字体(如 VS 选项对话框中所示)。

4

3 回答 3

13

看一下:

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

使用其中的一种结构,然后遍历族,实例化字体,获取 LogFont 值并检查 lfPitchAndFamily。

以下代码是即时编写且未经测试的,但类似以下的代码应该可以工作:

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......
        }
    }
}
于 2008-10-22T09:31:32.130 回答
6

AFAIK 你不能只使用 BCL 库来做到这一点。您必须使用 WinAPI 互操作。

您需要分析LOGFONT .lfPitchAndFamily 成员的 2 个最低位。有一个常数 FIXED_PITCH(意味着字体是固定宽度的)可以用作 lfPitchAndFamily 的位掩码。

这是一篇有用的文章:

枚举字体

枚举字体可能有点令人困惑,除非您想枚举系统上的所有字体,否则可能比 MSDN 建议的要困难一些。本文将准确解释您在系统上查找每种固定宽度字体所需的步骤,并列举每种字体的每种可能大小。

于 2008-10-22T08:44:32.273 回答
6

不幸的是,ToLogFont函数不会填充lfPitchAndFamily字段以更正值。在我的情况下,它始终为 0。

检测哪些字体可能是固定的一种近似值如下

    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() );
                }
            }

        }

请记住,它们是几个误报,例如 Wingdings

于 2011-12-17T13:18:58.327 回答