2012-09-14 5 views
2

Я видел How do I get all installed fixed-width fonts?, но я не могу заставить его работать:Как получить все моноширинные шрифты в Windows?

internal class NativeMethods 
{ 
    public const Int32 LF_FACESIZE = 32; 
    public const Int32 FIXED_PITCH = 1; 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public class LOGFONT 
    { 
     public Int32 lfHeight = 0; 
     public Int32 lfWidth = 0; 
     public Int32 lfEscapement = 0; 
     public Int32 lfOrientation = 0; 
     public Int32 lfWeight = 0; 
     public Byte lfItalic = 0; 
     public Byte lfUnderline = 0; 
     public Byte lfStrikeOut = 0; 
     public Byte lfCharSet = 0; 
     public Byte lfOutPrecision = 0; 
     public Byte lfClipPrecision = 0; 
     public Byte lfQuality = 0; 
     public Byte lfPitchAndFamily = 0; 

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] 
     public String lfFaceName = string.Empty; 
    } 
} 


public partial class MainForm : Form 
{ 
    private string font_names = null; 

    public MainForm() 
    { 
     InitializeComponent(); 

     StringBuilder sb = new StringBuilder(); 
     foreach (var font_family in FontFamily.Families) 
     { 
      if (font_family.IsStyleAvailable(FontStyle.Regular)) 
      { 
       var lf = new NativeMethods.LOGFONT(); 
       Font font = new Font(font_family, 9.0f); 
       font.ToLogFont(lf); 
       if ((lf.lfPitchAndFamily & 0x3) == NativeMethods.FIXED_PITCH) 
       { 
        sb.AppendLine(font_family.Name); 
       } 
      } 
     } 
     font_names = sb.ToString(); 
    } 

    private void MainForm_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.DrawString(font_names, SystemFonts.MessageBoxFont, SystemBrushes.WindowText, 10.0f, 10.0f); 
    } 
} 

Это не кажется, независимо от того, какой шрифт она, lfPitchAndFamily всегда равна нулю.

Итак, как получить все моноширинные шрифты?

ответ

3

Я думаю, что я буду использовать P/Invoke, чтобы сделать это:

internal class NativeMethods 
{ 
    public const Int32 LF_FACESIZE = 32; 
    public const Int32 LF_FULLFACESIZE = 64; 
    public const Int32 DEFAULT_CHARSET = 1; 
    public const Int32 FIXED_PITCH = 1; 
    public const Int32 TRUETYPE_FONTTYPE = 0x0004; 

    public delegate Int32 FONTENUMPROC(ref ENUMLOGFONT lpelf, ref NEWTEXTMETRIC lpntm, UInt32 FontType, IntPtr lParam); 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct LOGFONT 
    { 
     public Int32 lfHeight; 
     public Int32 lfWidth; 
     public Int32 lfEscapement; 
     public Int32 lfOrientation; 
     public Int32 lfWeight; 
     public Byte lfItalic; 
     public Byte lfUnderline; 
     public Byte lfStrikeOut; 
     public Byte lfCharSet; 
     public Byte lfOutPrecision; 
     public Byte lfClipPrecision; 
     public Byte lfQuality; 
     public Byte lfPitchAndFamily; 

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] 
     public String lfFaceName; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct TEXTMETRIC 
    { 
     public Int32 tmHeight; 
     public Int32 tmAscent; 
     public Int32 tmDescent; 
     public Int32 tmInternalLeading; 
     public Int32 tmExternalLeading; 
     public Int32 tmAveCharWidth; 
     public Int32 tmMaxCharWidth; 
     public Int32 tmWeight; 
     public Int32 tmOverhang; 
     public Int32 tmDigitizedAspectX; 
     public Int32 tmDigitizedAspectY; 
     public Char tmFirstChar; 
     public Char tmLastChar; 
     public Char tmDefaultChar; 
     public Char tmBreakChar; 
     public Byte tmItalic; 
     public Byte tmUnderlined; 
     public Byte tmStruckOut; 
     public Byte tmPitchAndFamily; 
     public Byte tmCharSet; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct ENUMLOGFONT 
    { 
     public LOGFONT elfLogFont; 

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FULLFACESIZE)] 
     public String elfFullName; 

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] 
     public String elfStyle; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct NEWTEXTMETRIC 
    { 
     public Int32 tmHeight; 
     public Int32 tmAscent; 
     public Int32 tmDescent; 
     public Int32 tmInternalLeading; 
     public Int32 tmExternalLeading; 
     public Int32 tmAveCharWidth; 
     public Int32 tmMaxCharWidth; 
     public Int32 tmWeight; 
     public Int32 tmOverhang; 
     public Int32 tmDigitizedAspectX; 
     public Int32 tmDigitizedAspectY; 
     public Char tmFirstChar; 
     public Char tmLastChar; 
     public Char tmDefaultChar; 
     public Char tmBreakChar; 
     public Byte tmItalic; 
     public Byte tmUnderlined; 
     public Byte tmStruckOut; 
     public Byte tmPitchAndFamily; 
     public Byte tmCharSet; 
     public UInt32 ntmFlags; 
     public UInt32 ntmSizeEM; 
     public UInt32 ntmCellHeight; 
     public UInt32 ntmAvgWidth; 
    } 

    [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
    public extern static Int32 EnumFontFamiliesEx(IntPtr hdc, ref LOGFONT lpLogfont, FONTENUMPROC lpEnumFontFamExProc, IntPtr lParam, UInt32 dwFlags); 
} 

internal static class Program 
{ 
    private static void Main() 
    { 
     Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); 
     IntPtr hdc = graphics.GetHdc(); 
     var logfont = new NativeMethods.LOGFONT() { lfCharSet = NativeMethods.DEFAULT_CHARSET }; 
     NativeMethods.EnumFontFamiliesEx(hdc, ref logfont, new NativeMethods.FONTENUMPROC(EnumFontFamExProc), IntPtr.Zero, 0); 
     graphics.ReleaseHdc(); 
    } 

    private static int EnumFontFamExProc(ref NativeMethods.ENUMLOGFONT lpelf, ref NativeMethods.NEWTEXTMETRIC lpntm, uint FontType, IntPtr lParam) 
    { 
     if ((lpelf.elfLogFont.lfPitchAndFamily & 0x3) == NativeMethods.FIXED_PITCH) 
     { 
      Console.WriteLine(lpelf.elfLogFont.lfFaceName); 
     } 
     return 1; 
    } 
} 
+0

Он работал. Одно замечание - для некоторых шрифтов выводятся дубликаты с префиксом «@», которые не являются правильными именами шрифтов. – Sam

Смежные вопросы