c# - 如何在 Windows 中获取所有等宽字体?

标签 c# windows fonts

我看过 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 始终为零。

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

最佳答案

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

关于c# - 如何在 Windows 中获取所有等宽字体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12417432/

相关文章:

c# - 需要多个锁对象?

windows - 将非 bat 扩展文件作为批处理文件运行

c# - IO操作的并发问题

java - 同一字体的多个实例化

css - 我怎样才能改变这个字体?

android - 通用网络安全字体

c# - 在 C# Winform 中设置 ListView 的位置位于 DataGridView Active Row 下方

c# - 解析 XML 的高效方法

c# - 为什么我在 ASP.NET 中收到 System.Data.SqlClient.SqlInternalConnection.OnError...?

c++ - 如果我知道此窗口的句柄,如何将 Ctrl + P 发送到窗口?