2008-10-22 2 views
13

Мне интересно, есть ли какие-либо простые способы получить список всех шрифтов фиксированной ширины (моноширинного), установленных в системе пользователя на C#?Как получить все установленные шрифты с фиксированной шириной?

Я использую .net 3.5, поэтому имею доступ к пространству имен WPF System.Windows.Media и LINQ, чтобы получить информацию о шрифте, но я не уверен, что я ищу.

Я хочу предоставить отфильтрованный список моноширинных шрифтов и/или выделить моноширинные шрифты из большего списка шрифтов (как видно в диалоговом окне опций VS).

ответ

11

Посмотри:

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

`lfPitchAndFamily` Безразлично 't work (always zero) и `(lf.lfPitchAndFamily^1)` дает ошибку (`CS0029: Невозможно неявно преобразовать тип' int 'в' bool'`) – Doc 2014-09-04 16:27:05

5

AFAIK вы не можете сделать это, используя только библиотеки BCL. Вы должны использовать WinAPI interop.

Вам необходимо проанализировать 2 самых младших бита LOGFONT .lfPitchAndFamily member. Существует константа FIXED_PITCH (означает, что шрифт имеет фиксированную ширину), который может использоваться в качестве битовой маски для lfPitchAndFamily.

Вот полезная статья:

Перечисление шрифтов может быть немного в заблуждение, и если вы не хотите перечислить все шрифты на вашей системе, может быть немного сложнее чем MSDN предлагает. Эта статья будет объясните, как именно вам нужно использовать , чтобы найти шрифт с фиксированной шириной на вашей системе, а также перечислить каждый размер для каждого пользователя. .

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

+0

0 - это« правильное »значение. Это означает `DEFAULT_PITCH`. – 2013-04-19 04:15:37