none
请问如何可以获取系统所有安装的等宽字体?(如何判断一个字体是否为等宽的?) RRS feed

  • 问题

  • 如题。

    比如在 Visual Studio 的选项的字体设置中的等宽字体被加粗显示。

    如可才能判断某个字体是否为等宽的?


    EFanZh

    2012年9月14日 11:44

答案

  • 我猜我只能用 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;
        }
    }

    EFanZh

    • 已标记为答案 EFanZh 2012年9月18日 2:32
    2012年9月18日 2:25

全部回复

  • Hi EFanZh,

    请参考下面的帖子。

    How do I get all installed fixed-width fonts?

    http://stackoverflow.com/questions/224865/how-do-i-get-all-installed-fixed-width-fonts


    Bob Shen [MSFT]
    MSDN Community Support | Feedback to us


    2012年9月17日 9:27
    版主
  • 我试过了,但貌似不管用:

    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 一直为 0。

    • 已编辑 EFanZh 2012年9月17日 9:53
    2012年9月17日 9:52
  • 我猜我只能用 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;
        }
    }

    EFanZh

    • 已标记为答案 EFanZh 2012年9月18日 2:32
    2012年9月18日 2:25