2008-10-22 13 views
13

Ich frage mich, ob es eine einfache Möglichkeit gibt, eine Liste aller Fonts mit fester Breite (monospaced) zu erhalten, die auf dem System eines Benutzers in C# installiert sind.Wie bekomme ich alle installierten Schriften mit fester Breite?

Ich benutze .net 3.5 so haben Sie Zugriff auf den WPF System.Windows.Media Namespace und LINQ Font-Informationen zu erhalten, aber ich bin mir nicht sicher, was ich suche.

Ich möchte in der Lage sein, eine gefilterte Liste von monospaced Schriftarten und/oder wählen Sie monospaced Schriftarten aus einer größeren Liste von Schriftarten (wie im Dialogfeld VS-Optionen zu sehen).

Antwort

11

Werfen Sie einen Blick auf:

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

Verwenden Sie eine der Strukturen dort, dann Schleife über Familien, eine Schrift Instanziierung und den LogFont Wert bekommen und lfPitchAndFamily überprüfen.

Der folgende Code wird im laufenden Betrieb geschrieben und ungetestet, aber so etwas wie die folgenden funktionieren soll:

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' doesn 't work (immer Null) und '(lf.lfPitchAndFamily^1)' ergibt einen Fehler ('CS0029: Typ' int 'kann nicht implizit in' bool' umgewandelt werden) – Doc

5

AFAIK Sie können es nicht nur mit BCL-Bibliotheken tun. Sie müssen WinAPI Interop verwenden.

Sie müssen 2 unterste Bits von LOGFONT .lfPitchAndFamily-Mitglied analysieren. Es gibt eine Konstante FIXED_PITCH (bedeutet, dass die Schriftart feste Breite ist), die als eine Bitmaske für IfPitchAndFamily verwendet werden kann. Hier

ist ein nützlicher Artikel:

Aufzählen Fonts etwas verwirrend sein kann, und es sei denn, Sie enumerate möchten, dass alle Schriften auf Ihrem System, kann ein wenig schwieriger sein als schlägt MSDN vor. Dieser Artikel wird erklären genau die Schritte, die Sie benötigen verwenden, um jede Schriftart mit fester Breite auf Ihr System zu finden, und auch jede mögliche Größe für jede einzelne Schriftart aufzulisten.

6

Leider ToLogFont Funktion füllt nicht lfPitchAndFamily Feldwerte zu korrigieren. In meinem Fall ist es immer 0.

Eine Annäherung zu erkennen, welche Schriften festgelegt werden könnte, ist die folgende

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

     } 

Denken Sie daran, dass sie zum Beispiel mehrere Fehlalarme sind Wingdings

+0

0 ist ein" korrekter "Wert. Es bedeutet 'DEFAULT_PITCH'. –

+0

Viel zu _hacky_ und anfällig für falsche Positive (wie du erwähnt hast) :( – Doc