【问题标题】:How to get all monospaced fonts in Windows?如何在 Windows 中获取所有等宽字体?
【发布时间】:2012-09-14 02:39:56
【问题描述】:

我见过How do I get all installed fixed-width fonts?,但我不能让它工作:

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 总是为零。

那么如何获得所有等宽字体呢?

【问题讨论】:

    标签: c# windows fonts


    【解决方案1】:

    我想我将只使用 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;
        }
    }
    

    【讨论】:

    • 成功了。需要注意的一件事 - 对于某些字体,它输出带有“@”前缀的重复项,这不是字体的正确名称。
    猜你喜欢
    • 2020-12-17
    • 2011-02-13
    • 2010-09-18
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多