如何知道silverlight中的本地字体名称

发布于 2024-08-30 07:10:55 字数 500 浏览 5 评论 0原文

在 silverlight 4 中,我需要知道我的机器中的所有字体名称。 使用....

...

 var typefaces = System.Windows.Media.Fonts.SystemTypefaces;

        foreach (System.Windows.Media.Typeface face in typefaces)
        {

            System.Windows.Media.GlyphTypeface a;
            face.TryGetGlyphTypeface(out a);
            FontSource fs = new FontSource(a);

           var b = a.FontFileName;

...

我只能获取FontFileName,但实际上我们需要字体名来显示它......

如何获得这样的信息?

谢谢大家!

in silverlight 4 I need to know all the font names in my machines.
Using....

...

 var typefaces = System.Windows.Media.Fonts.SystemTypefaces;

        foreach (System.Windows.Media.Typeface face in typefaces)
        {

            System.Windows.Media.GlyphTypeface a;
            face.TryGetGlyphTypeface(out a);
            FontSource fs = new FontSource(a);

           var b = a.FontFileName;

...

I only can get FontFileName but actually we'd need the fontname for showing it....

How can get such info?

thanks you all!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

本王不退位尔等都是臣 2024-09-06 07:10:55

为 Silverlight 生成查找表:

WPF 具有执行此操作的属性,但 Silverlight 没有。

如果您在调试器中查看 System.Windows.Media.Typeface 对象,除了 2 个版本号和 FontUri(读取文件名)之外,字体不包含任何内容。

您可以通过在 WPF 下运行代码来生成查找字典,以提取所有文件名和匹配的字体名,但您需要在安装了要覆盖的每种字体的计算机上执行此操作。

下面的 WPF 代码提取这样一个表(该表包含所有语言的字体名称,因此您可能需要向其中添加一个过滤器,例如通过“en-us”):

    foreach (var font in System.Windows.Media.Fonts.SystemTypefaces)
    {
        System.Windows.Media.GlyphTypeface glyphTypeface;
        font.TryGetGlyphTypeface(out glyphTypeface);
        var dictionary = font.FaceNames;
        foreach (var language in dictionary.Keys)
        {
            Debug.WriteLine(string.Format("\"{0}\", \"{1}\", \"{2}\"", glyphTypeface.FontUri.Segments[glyphTypeface.FontUri.Segments.Count()-1], language, dictionary[language]));
        }
    }

部分输出如下所示,可以很容易地在 Silverlight 中格式化为表或作为字典加载:

"ARIAL.TTF", "ca-es", "Normal"
"ARIAL.TTF", "cs-cz", "obyčejné"
"ARIAL.TTF", "da-dk", "normal"
"ARIAL.TTF", "de-de", "Standard"
"ARIAL.TTF", "el-gr", "Κανονικά"
"ARIAL.TTF", "en-us", "Regular"
"ARIAL.TTF", "es-es", "Normal"
"ARIAL.TTF", "es-mx", "Normal"
"ARIAL.TTF", "eu-es", "Arrunta"
"ARIAL.TTF", "fi-fi", "Normaali"
"ARIAL.TTF", "fr-ca", "Normal"
"ARIAL.TTF", "fr-fr", "Normal"
"ARIAL.TTF", "hu-hu", "Normál"
"ARIAL.TTF", "it-it", "Normale"
"ARIAL.TTF", "nb-no", "Normal"
"ARIAL.TTF", "nl-nl", "Standaard"
"ARIAL.TTF", "pl-pl", "Normalny"
"ARIAL.TTF", "pt-br", "Normal"
"ARIAL.TTF", "pt-pt", "Normal"
"ARIAL.TTF", "ru-ru", "Обычный"
"ARIAL.TTF", "sk-sk", "Normálne"
"ARIAL.TTF", "sl-si", "Navadno"
"ARIAL.TTF", "sv-se", "Normal"
"ARIAL.TTF", "tr-tr", "Normal"
"ARIAL.TTF", "vi-vn", "thường"
"ARIALN.TTF", "en-us", "Narrow"
"ARIALI.TTF", "ca-es", "Cursiva"
"ARIALI.TTF", "cs-cz", "kurzíva"
"ARIALI.TTF", "da-dk", "kursiv"
"ARIALI.TTF", "de-de", "Kursiv"
"ARIALI.TTF", "el-gr", "Πλάγια"
"ARIALI.TTF", "en-us", "Italic"
"ARIALI.TTF", "es-es", "Cursiva"
"ARIALI.TTF", "es-mx", "Cursiva"
"ARIALI.TTF", "eu-es", "Etzana"
"ARIALI.TTF", "fi-fi", "Kursivoitu"
"ARIALI.TTF", "fr-ca", "Italique"
"ARIALI.TTF", "fr-fr", "Italique"
"ARIALI.TTF", "hu-hu", "Dőlt"
"ARIALI.TTF", "it-it", "Corsivo"
"ARIALI.TTF", "nb-no", "Kursiv"
"ARIALI.TTF", "nl-nl", "Cursief"
"ARIALI.TTF", "pl-pl", "Kursywa"
"ARIALI.TTF", "pt-br", "Itálico"
"ARIALI.TTF", "pt-pt", "Itálico"
"ARIALI.TTF", "ru-ru", "Курсив"
"ARIALI.TTF", "sk-sk", "Kurzíva"
"ARIALI.TTF", "sl-si", "Poševno"
"ARIALI.TTF", "sv-se", "Kursiv"
"ARIALI.TTF", "tr-tr", "İtalik"
"ARIALI.TTF", "vi-vn", "nghiêng"
"ARIALNI.TTF", "en-us", "Narrow"
"ARIALBD.TTF", "ca-es", "Negreta"
"ARIALBD.TTF", "cs-cz", "tučné"
"ARIALBD.TTF", "da-dk", "fed"
"ARIALBD.TTF", "de-de", "Fett"
"ARIALBD.TTF", "el-gr", "Έντονα"
"ARIALBD.TTF", "en-us", "Bold"
"ARIALBD.TTF", "es-es", "Negrita"
"ARIALBD.TTF", "es-mx", "Negrita"
"ARIALBD.TTF", "eu-es", "Lodia"
"ARIALBD.TTF", "fi-fi", "Lihavoitu"

Generate a lookup table for Silverlight:

WPF has the properties to do this, but Silverlight does not.

If you look at the System.Windows.Media.Typeface objects in the debugger the fonts do not contain anything except 2 version numbers and the FontUri (read filename).

You could generate a lookup dictionary by running code under WPF to extract all the filenames and matching fontnames, but you need to do that on a machine with every font installed that you want to cover.

The WPF code below extracts such a table (this one contains the font names in all languages, so you will probably want to add a filter to it e.g. by "en-us"):

    foreach (var font in System.Windows.Media.Fonts.SystemTypefaces)
    {
        System.Windows.Media.GlyphTypeface glyphTypeface;
        font.TryGetGlyphTypeface(out glyphTypeface);
        var dictionary = font.FaceNames;
        foreach (var language in dictionary.Keys)
        {
            Debug.WriteLine(string.Format("\"{0}\", \"{1}\", \"{2}\"", glyphTypeface.FontUri.Segments[glyphTypeface.FontUri.Segments.Count()-1], language, dictionary[language]));
        }
    }

Part of the output is shown below and could be easily formatted into a table or loaded as a dictionary in Silverlight:

"ARIAL.TTF", "ca-es", "Normal"
"ARIAL.TTF", "cs-cz", "obyčejné"
"ARIAL.TTF", "da-dk", "normal"
"ARIAL.TTF", "de-de", "Standard"
"ARIAL.TTF", "el-gr", "Κανονικά"
"ARIAL.TTF", "en-us", "Regular"
"ARIAL.TTF", "es-es", "Normal"
"ARIAL.TTF", "es-mx", "Normal"
"ARIAL.TTF", "eu-es", "Arrunta"
"ARIAL.TTF", "fi-fi", "Normaali"
"ARIAL.TTF", "fr-ca", "Normal"
"ARIAL.TTF", "fr-fr", "Normal"
"ARIAL.TTF", "hu-hu", "Normál"
"ARIAL.TTF", "it-it", "Normale"
"ARIAL.TTF", "nb-no", "Normal"
"ARIAL.TTF", "nl-nl", "Standaard"
"ARIAL.TTF", "pl-pl", "Normalny"
"ARIAL.TTF", "pt-br", "Normal"
"ARIAL.TTF", "pt-pt", "Normal"
"ARIAL.TTF", "ru-ru", "Обычный"
"ARIAL.TTF", "sk-sk", "Normálne"
"ARIAL.TTF", "sl-si", "Navadno"
"ARIAL.TTF", "sv-se", "Normal"
"ARIAL.TTF", "tr-tr", "Normal"
"ARIAL.TTF", "vi-vn", "thường"
"ARIALN.TTF", "en-us", "Narrow"
"ARIALI.TTF", "ca-es", "Cursiva"
"ARIALI.TTF", "cs-cz", "kurzíva"
"ARIALI.TTF", "da-dk", "kursiv"
"ARIALI.TTF", "de-de", "Kursiv"
"ARIALI.TTF", "el-gr", "Πλάγια"
"ARIALI.TTF", "en-us", "Italic"
"ARIALI.TTF", "es-es", "Cursiva"
"ARIALI.TTF", "es-mx", "Cursiva"
"ARIALI.TTF", "eu-es", "Etzana"
"ARIALI.TTF", "fi-fi", "Kursivoitu"
"ARIALI.TTF", "fr-ca", "Italique"
"ARIALI.TTF", "fr-fr", "Italique"
"ARIALI.TTF", "hu-hu", "Dőlt"
"ARIALI.TTF", "it-it", "Corsivo"
"ARIALI.TTF", "nb-no", "Kursiv"
"ARIALI.TTF", "nl-nl", "Cursief"
"ARIALI.TTF", "pl-pl", "Kursywa"
"ARIALI.TTF", "pt-br", "Itálico"
"ARIALI.TTF", "pt-pt", "Itálico"
"ARIALI.TTF", "ru-ru", "Курсив"
"ARIALI.TTF", "sk-sk", "Kurzíva"
"ARIALI.TTF", "sl-si", "Poševno"
"ARIALI.TTF", "sv-se", "Kursiv"
"ARIALI.TTF", "tr-tr", "İtalik"
"ARIALI.TTF", "vi-vn", "nghiêng"
"ARIALNI.TTF", "en-us", "Narrow"
"ARIALBD.TTF", "ca-es", "Negreta"
"ARIALBD.TTF", "cs-cz", "tučné"
"ARIALBD.TTF", "da-dk", "fed"
"ARIALBD.TTF", "de-de", "Fett"
"ARIALBD.TTF", "el-gr", "Έντονα"
"ARIALBD.TTF", "en-us", "Bold"
"ARIALBD.TTF", "es-es", "Negrita"
"ARIALBD.TTF", "es-mx", "Negrita"
"ARIALBD.TTF", "eu-es", "Lodia"
"ARIALBD.TTF", "fi-fi", "Lihavoitu"
娇妻 2024-09-06 07:10:55

查看此答案。

我最终使用了Fonts.SystemFontFamilies 在 SERVER(PresentationCore dll 中)上,通过服务调用将结果(来自 Source 属性)发送到 Silverlight 应用程序。不完美,但我能找到的最好的。

See this answer.

I ended up using Fonts.SystemFontFamilies on the SERVER (in the PresentationCore dll), sending the result (from the Source property) via a service call to the Silverlight app. Not perfect, but the best I could find.

燕归巢 2024-09-06 07:10:55

我还尝试使用 System.Windows.Media.Fonts.SystemTypefaces 但正如您提到的它只提供字体文件名。在网上进行了大量阅读和研究后,我决定使用 P/Invoke 来解决这个问题。如果您可以像我一样选择以 OOB(浏览器外)方式运行应用程序并提高信任度,那么以下 P/Invoke 解决方案将会非常有效。感谢 www.pinvoke.net 提供的所有方法/结构定义。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace Utils
{
  [SecurityCritical]
  public class FontsCollection
  {

    #region Types
    delegate int EnumFontDelegate(IntPtr lpelfe, IntPtr lpntme, EnumFontsType FontType, int lParam);
    enum EnumFontsType
    {
      DEVICE_FONTTYPE = 0x0000,
      RASTER_FONTTYPE = 0x0001,
      TRUETYPE_FONTTYPE = 0x0004
    };

    #region LOGFONT definition
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class LOGFONT
    {
      public int lfHeight;
      public int lfWidth;
      public int lfEscapement;
      public int lfOrientation;
      public FontWeight lfWeight;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfItalic;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfUnderline;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfStrikeOut;
      public FontCharSet lfCharSet;
      public FontPrecision lfOutPrecision;
      public FontClipPrecision lfClipPrecision;
      public FontQuality lfQuality;
      public FontPitchAndFamily lfPitchAndFamily;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
      public string lfFaceName;
    }

    public enum FontWeight : int
    {
      FW_DONTCARE = 0,
      FW_THIN = 100,
      FW_EXTRALIGHT = 200,
      FW_LIGHT = 300,
      FW_NORMAL = 400,
      FW_MEDIUM = 500,
      FW_SEMIBOLD = 600,
      FW_BOLD = 700,
      FW_EXTRABOLD = 800,
      FW_HEAVY = 900,
    }

    public enum FontCharSet : byte
    {
      ANSI_CHARSET = 0,
      DEFAULT_CHARSET = 1,
      SYMBOL_CHARSET = 2,
      SHIFTJIS_CHARSET = 128,
      HANGEUL_CHARSET = 129,
      HANGUL_CHARSET = 129,
      GB2312_CHARSET = 134,
      CHINESEBIG5_CHARSET = 136,
      OEM_CHARSET = 255,
      JOHAB_CHARSET = 130,
      HEBREW_CHARSET = 177,
      ARABIC_CHARSET = 178,
      GREEK_CHARSET = 161,
      TURKISH_CHARSET = 162,
      VIETNAMESE_CHARSET = 163,
      THAI_CHARSET = 222,
      EASTEUROPE_CHARSET = 238,
      RUSSIAN_CHARSET = 204,
      MAC_CHARSET = 77,
      BALTIC_CHARSET = 186,
    }

    public enum FontPrecision : byte
    {
      OUT_DEFAULT_PRECIS = 0,
      OUT_STRING_PRECIS = 1,
      OUT_CHARACTER_PRECIS = 2,
      OUT_STROKE_PRECIS = 3,
      OUT_TT_PRECIS = 4,
      OUT_DEVICE_PRECIS = 5,
      OUT_RASTER_PRECIS = 6,
      OUT_TT_ONLY_PRECIS = 7,
      OUT_OUTLINE_PRECIS = 8,
      OUT_SCREEN_OUTLINE_PRECIS = 9,
      OUT_PS_ONLY_PRECIS = 10,
    }

    public enum FontClipPrecision : byte
    {
      CLIP_DEFAULT_PRECIS = 0,
      CLIP_CHARACTER_PRECIS = 1,
      CLIP_STROKE_PRECIS = 2,
      CLIP_MASK = 0xf,
      CLIP_LH_ANGLES = (1 << 4),
      CLIP_TT_ALWAYS = (2 << 4),
      CLIP_DFA_DISABLE = (4 << 4),
      CLIP_EMBEDDED = (8 << 4),
    }

    public enum FontQuality : byte
    {
      DEFAULT_QUALITY = 0,
      DRAFT_QUALITY = 1,
      PROOF_QUALITY = 2,
      NONANTIALIASED_QUALITY = 3,
      ANTIALIASED_QUALITY = 4,
      CLEARTYPE_QUALITY = 5,
      CLEARTYPE_NATURAL_QUALITY = 6,
    }

    [Flags]
    public enum FontPitchAndFamily : byte
    {
      DEFAULT_PITCH = 0,
      FIXED_PITCH = 1,
      VARIABLE_PITCH = 2,
      FF_DONTCARE = (0 << 4),
      FF_ROMAN = (1 << 4),
      FF_SWISS = (2 << 4),
      FF_MODERN = (3 << 4),
      FF_SCRIPT = (4 << 4),
      FF_DECORATIVE = (5 << 4),
    }
    #endregion

    #endregion

    #region Fields
    private IList<string> _fontNames;
    private IntPtr _fpEnumProc;
    private EnumFontDelegate _enumFontDelegate;
    private static FontsCollection _default;
    #endregion

    #region External APIs
    [DllImport("gdi32.dll")]
    private static extern int EnumFontFamilies(IntPtr hdc, string fontFamily, IntPtr lpEnumFontFamExProc, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll")]
    private static extern IntPtr GetDC(IntPtr hwnd);

    [DllImport("user32.dll")]
    private static extern IntPtr ReleaseDC(IntPtr hdc); 
    #endregion

    #region Properties
    public IEnumerable<string> InstalledFontNames
    {
      get
      {
        if (null == _fontNames)
        {
          BuildFontList();
        }
        return _fontNames.AsEnumerable();
      }
    }
    public static FontsCollection Default
    {
      get
      {
        return _default ?? (_default = new FontsCollection());
      }
    }
    #endregion

    #region Win32 callback
    [System.Runtime.InteropServices.AllowReversePInvokeCalls]
    private int EnumFontFamiliesExProc(IntPtr lpelfe, IntPtr lpntme, EnumFontsType FontType, int lParam)
    {
      LOGFONT logFont = new LOGFONT();
      Marshal.PtrToStructure(lpelfe, logFont);

      //we dont like duplicate names
      if (!_fontNames.Contains(logFont.lfFaceName, StringComparer.OrdinalIgnoreCase))
      {
        _fontNames.Add(logFont.lfFaceName);
      }
      // Non-zero return continues enumerating
      return 1;
    }

    #endregion

    #region Methods
        private void BuildFontList()
    {
      // Need an HDC to pass to EnumFontFamilies
      IntPtr hwnd = GetDesktopWindow();
      IntPtr hdc = GetDC(hwnd);
      try
      {
        LOGFONT logFont = new LOGFONT();

        _enumFontDelegate = new EnumFontDelegate(EnumFontFamiliesExProc);
        _fpEnumProc = Marshal.GetFunctionPointerForDelegate(_enumFontDelegate);
        _fontNames = new List<String>();
        EnumFontFamilies(hdc, null, _fpEnumProc, IntPtr.Zero);
        _fontNames = _fontNames.OrderBy(font => font).ToList();
      }
      finally
      {
        if (hdc != IntPtr.Zero)
        {
          ReleaseDC(hdc);
        }
      }
    }

      #endregion  
  }
}

使用该类非常简单。下面是一个示例 XAML 标记

<UserControl x:Class="SLTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

    <Grid x:Name="LayoutRoot" Background="White">
        <ComboBox ItemsSource="{Binding InstalledFontNames}" Height="50"/>
    </Grid>
</UserControl>

在 XAML 页面的代码后面,添加以下内容

public partial class MainPage : UserControl
{
    public MainPage()
    {
      InitializeComponent();
      DataContext = Utils.FontsCollection.Default;
    }
}

I also tried to use System.Windows.Media.Fonts.SystemTypefaces but as you mentioned it only gives the font file name. After doing a lot of reading and research on the web, I decided to use P/Invoke to solve this. If you have the choice of running your application as OOB (Out of Browser) with elevated trust as I had, the following P/Invoke solution will work great. Thanks to www.pinvoke.net for all of the method/structure definitions.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace Utils
{
  [SecurityCritical]
  public class FontsCollection
  {

    #region Types
    delegate int EnumFontDelegate(IntPtr lpelfe, IntPtr lpntme, EnumFontsType FontType, int lParam);
    enum EnumFontsType
    {
      DEVICE_FONTTYPE = 0x0000,
      RASTER_FONTTYPE = 0x0001,
      TRUETYPE_FONTTYPE = 0x0004
    };

    #region LOGFONT definition
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class LOGFONT
    {
      public int lfHeight;
      public int lfWidth;
      public int lfEscapement;
      public int lfOrientation;
      public FontWeight lfWeight;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfItalic;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfUnderline;
      [MarshalAs(UnmanagedType.U1)]
      public bool lfStrikeOut;
      public FontCharSet lfCharSet;
      public FontPrecision lfOutPrecision;
      public FontClipPrecision lfClipPrecision;
      public FontQuality lfQuality;
      public FontPitchAndFamily lfPitchAndFamily;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
      public string lfFaceName;
    }

    public enum FontWeight : int
    {
      FW_DONTCARE = 0,
      FW_THIN = 100,
      FW_EXTRALIGHT = 200,
      FW_LIGHT = 300,
      FW_NORMAL = 400,
      FW_MEDIUM = 500,
      FW_SEMIBOLD = 600,
      FW_BOLD = 700,
      FW_EXTRABOLD = 800,
      FW_HEAVY = 900,
    }

    public enum FontCharSet : byte
    {
      ANSI_CHARSET = 0,
      DEFAULT_CHARSET = 1,
      SYMBOL_CHARSET = 2,
      SHIFTJIS_CHARSET = 128,
      HANGEUL_CHARSET = 129,
      HANGUL_CHARSET = 129,
      GB2312_CHARSET = 134,
      CHINESEBIG5_CHARSET = 136,
      OEM_CHARSET = 255,
      JOHAB_CHARSET = 130,
      HEBREW_CHARSET = 177,
      ARABIC_CHARSET = 178,
      GREEK_CHARSET = 161,
      TURKISH_CHARSET = 162,
      VIETNAMESE_CHARSET = 163,
      THAI_CHARSET = 222,
      EASTEUROPE_CHARSET = 238,
      RUSSIAN_CHARSET = 204,
      MAC_CHARSET = 77,
      BALTIC_CHARSET = 186,
    }

    public enum FontPrecision : byte
    {
      OUT_DEFAULT_PRECIS = 0,
      OUT_STRING_PRECIS = 1,
      OUT_CHARACTER_PRECIS = 2,
      OUT_STROKE_PRECIS = 3,
      OUT_TT_PRECIS = 4,
      OUT_DEVICE_PRECIS = 5,
      OUT_RASTER_PRECIS = 6,
      OUT_TT_ONLY_PRECIS = 7,
      OUT_OUTLINE_PRECIS = 8,
      OUT_SCREEN_OUTLINE_PRECIS = 9,
      OUT_PS_ONLY_PRECIS = 10,
    }

    public enum FontClipPrecision : byte
    {
      CLIP_DEFAULT_PRECIS = 0,
      CLIP_CHARACTER_PRECIS = 1,
      CLIP_STROKE_PRECIS = 2,
      CLIP_MASK = 0xf,
      CLIP_LH_ANGLES = (1 << 4),
      CLIP_TT_ALWAYS = (2 << 4),
      CLIP_DFA_DISABLE = (4 << 4),
      CLIP_EMBEDDED = (8 << 4),
    }

    public enum FontQuality : byte
    {
      DEFAULT_QUALITY = 0,
      DRAFT_QUALITY = 1,
      PROOF_QUALITY = 2,
      NONANTIALIASED_QUALITY = 3,
      ANTIALIASED_QUALITY = 4,
      CLEARTYPE_QUALITY = 5,
      CLEARTYPE_NATURAL_QUALITY = 6,
    }

    [Flags]
    public enum FontPitchAndFamily : byte
    {
      DEFAULT_PITCH = 0,
      FIXED_PITCH = 1,
      VARIABLE_PITCH = 2,
      FF_DONTCARE = (0 << 4),
      FF_ROMAN = (1 << 4),
      FF_SWISS = (2 << 4),
      FF_MODERN = (3 << 4),
      FF_SCRIPT = (4 << 4),
      FF_DECORATIVE = (5 << 4),
    }
    #endregion

    #endregion

    #region Fields
    private IList<string> _fontNames;
    private IntPtr _fpEnumProc;
    private EnumFontDelegate _enumFontDelegate;
    private static FontsCollection _default;
    #endregion

    #region External APIs
    [DllImport("gdi32.dll")]
    private static extern int EnumFontFamilies(IntPtr hdc, string fontFamily, IntPtr lpEnumFontFamExProc, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll")]
    private static extern IntPtr GetDC(IntPtr hwnd);

    [DllImport("user32.dll")]
    private static extern IntPtr ReleaseDC(IntPtr hdc); 
    #endregion

    #region Properties
    public IEnumerable<string> InstalledFontNames
    {
      get
      {
        if (null == _fontNames)
        {
          BuildFontList();
        }
        return _fontNames.AsEnumerable();
      }
    }
    public static FontsCollection Default
    {
      get
      {
        return _default ?? (_default = new FontsCollection());
      }
    }
    #endregion

    #region Win32 callback
    [System.Runtime.InteropServices.AllowReversePInvokeCalls]
    private int EnumFontFamiliesExProc(IntPtr lpelfe, IntPtr lpntme, EnumFontsType FontType, int lParam)
    {
      LOGFONT logFont = new LOGFONT();
      Marshal.PtrToStructure(lpelfe, logFont);

      //we dont like duplicate names
      if (!_fontNames.Contains(logFont.lfFaceName, StringComparer.OrdinalIgnoreCase))
      {
        _fontNames.Add(logFont.lfFaceName);
      }
      // Non-zero return continues enumerating
      return 1;
    }

    #endregion

    #region Methods
        private void BuildFontList()
    {
      // Need an HDC to pass to EnumFontFamilies
      IntPtr hwnd = GetDesktopWindow();
      IntPtr hdc = GetDC(hwnd);
      try
      {
        LOGFONT logFont = new LOGFONT();

        _enumFontDelegate = new EnumFontDelegate(EnumFontFamiliesExProc);
        _fpEnumProc = Marshal.GetFunctionPointerForDelegate(_enumFontDelegate);
        _fontNames = new List<String>();
        EnumFontFamilies(hdc, null, _fpEnumProc, IntPtr.Zero);
        _fontNames = _fontNames.OrderBy(font => font).ToList();
      }
      finally
      {
        if (hdc != IntPtr.Zero)
        {
          ReleaseDC(hdc);
        }
      }
    }

      #endregion  
  }
}

Using the class is very simple. Below is a sample XAML markup

<UserControl x:Class="SLTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

    <Grid x:Name="LayoutRoot" Background="White">
        <ComboBox ItemsSource="{Binding InstalledFontNames}" Height="50"/>
    </Grid>
</UserControl>

In the code behind of the XAML page, add the following

public partial class MainPage : UserControl
{
    public MainPage()
    {
      InitializeComponent();
      DataContext = Utils.FontsCollection.Default;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文