【问题标题】:How do I get all installed fixed-width fonts?如何获取所有已安装的固定宽度字体?
【发布时间】:2010-09-18 12:00:19
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# wpf fonts monospace


    【解决方案1】:

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

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

    这是一篇有用的文章:

    Enumerating Fonts

    枚举字体可能会有点 令人困惑,除非你想 枚举系统上的所有字体, 可能比 MSDN 建议。本文将 准确解释您需要执行的步骤 用于查找每个固定宽度的字体 您的系统,并枚举每个 每个人可能的大小 字体。

    【讨论】:

      【解决方案2】:

      很遗憾,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

      【讨论】:

      • 方式太 hacky 并且容易出现误报(正如你提到的):(
      • 如果您只想运行一次以进行调试输出,这非常有用。
      【解决方案3】:

      看看:

      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......
              }
          }
      }
      

      【讨论】:

      • lfPitchAndFamily 不起作用(始终为零)并且(lf.lfPitchAndFamily ^ 1) 给出错误(CS0029: Cannot implicitly convert type 'int' to 'bool'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      相关资源
      最近更新 更多