I'm wondering if there are any simple ways to get a list of all fixed-width (monospaced) fonts installed on a user's system in C#?
我想知道是否有任何简单的方法来获取在C#中安装在用户系统上的所有固定宽度(等宽字体)字体的列表?
I'm using .net 3.5 so have access to the WPF System.Windows.Media namespace and LINQ to get font information, but I'm not sure what I'm looking for.
我正在使用.net 3.5,因此可以访问WPF System.Windows.Media命名空间和LINQ来获取字体信息,但我不确定我在寻找什么。
I want to be able to provide a filtered list of monospaced fonts and/or pick out monospaced fonts from a larger list of fonts (as seen in the VS options dialog).
我希望能够提供一个过滤的等宽字体列表和/或从更大的字体列表中选择等宽字体(如VS选项对话框中所示)。
3 个解决方案
#1
11
Have a look at:
看一下:
http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html
http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html
Use one of the structures in there, then loop over families, instantiating a Font, and getting the LogFont value and checking lfPitchAndFamily.
使用其中的一个结构,然后循环遍历族,实例化Font,获取LogFont值并检查lfPitchAndFamily。
The following code is written on the fly and untested, but something like the following should work:
下面的代码是动态编写的,未经测试,但以下代码应该有效:
foreach (FontFamily ff in System.Drawing.FontFamily.Families)
{
if (ff.IsStyleAvailable(FontStyle.Regular))
{
Font font = new Font(ff, 10);
LOGFONT lf = new LOGFONT();
font.ToLogFont(lf);
if (lf.lfPitchAndFamily ^ 1)
{
do stuff here......
}
}
}
#2
6
Unfortunately ToLogFont function does not fill lfPitchAndFamily field to correct values. In my case it's always 0.
不幸的是,ToLogFont函数没有填充lfPitchAndFamily字段来更正值。在我的情况下,它总是0。
One approximation to detect which fonts might be fixed is the following
检测哪些字体可能被修复的一个近似值如下
foreach ( FontFamily ff in FontFamily.Families ) {
if ( ff.IsStyleAvailable( FontStyle.Regular ) ) {
float diff;
using ( Font font = new Font( ff, 16 ) ) {
diff = TextRenderer.MeasureText( "WWW", font ).Width - TextRenderer.MeasureText( "...", font ).Width;
}
if ( Math.Abs( diff ) < float.Epsilon * 2 ) {
Debug.WriteLine( ff.ToString() );
}
}
}
Keep in mind that they are several false positives, for example Wingdings
请记住,他们是几个误报,例如Wingdings
#3
5
AFAIK you can't do it using BCL libraries only. You have to use WinAPI interop.
AFAIK你不能只使用BCL库。您必须使用WinAPI互操作。
You need to analyze 2 lowest bits of LOGFONT.lfPitchAndFamily member. There is a constant FIXED_PITCH (means that font is fixed-width) that can be used as a bit mask for lfPitchAndFamily.
您需要分析LOGFONT.lfPitchAndFamily成员的2个最低位。有一个常量FIXED_PITCH(表示字体是固定宽度),可用作lfPitchAndFamily的位掩码。
Here is a useful article:
这是一篇有用的文章:
枚举字体
Enumerating fonts can be a little confusing, and unless you want to enumerate all fonts on your system, can be a little more difficult than MSDN suggests. This article will explain exactly the steps you need to use to find every fixed-width font on your system, and also enumerate every possible size for each individual font.
枚举字体可能有点令人困惑,除非你想枚举系统中的所有字体,否则比MSDN建议的要困难一些。本文将准确解释您在系统中查找每个固定宽度字体所需的步骤,并列出每种字体的每个可能大小。
#1
11
Have a look at:
看一下:
http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html
http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html
Use one of the structures in there, then loop over families, instantiating a Font, and getting the LogFont value and checking lfPitchAndFamily.
使用其中的一个结构,然后循环遍历族,实例化Font,获取LogFont值并检查lfPitchAndFamily。
The following code is written on the fly and untested, but something like the following should work:
下面的代码是动态编写的,未经测试,但以下代码应该有效:
foreach (FontFamily ff in System.Drawing.FontFamily.Families)
{
if (ff.IsStyleAvailable(FontStyle.Regular))
{
Font font = new Font(ff, 10);
LOGFONT lf = new LOGFONT();
font.ToLogFont(lf);
if (lf.lfPitchAndFamily ^ 1)
{
do stuff here......
}
}
}
#2
6
Unfortunately ToLogFont function does not fill lfPitchAndFamily field to correct values. In my case it's always 0.
不幸的是,ToLogFont函数没有填充lfPitchAndFamily字段来更正值。在我的情况下,它总是0。
One approximation to detect which fonts might be fixed is the following
检测哪些字体可能被修复的一个近似值如下
foreach ( FontFamily ff in FontFamily.Families ) {
if ( ff.IsStyleAvailable( FontStyle.Regular ) ) {
float diff;
using ( Font font = new Font( ff, 16 ) ) {
diff = TextRenderer.MeasureText( "WWW", font ).Width - TextRenderer.MeasureText( "...", font ).Width;
}
if ( Math.Abs( diff ) < float.Epsilon * 2 ) {
Debug.WriteLine( ff.ToString() );
}
}
}
Keep in mind that they are several false positives, for example Wingdings
请记住,他们是几个误报,例如Wingdings
#3
5
AFAIK you can't do it using BCL libraries only. You have to use WinAPI interop.
AFAIK你不能只使用BCL库。您必须使用WinAPI互操作。
You need to analyze 2 lowest bits of LOGFONT.lfPitchAndFamily member. There is a constant FIXED_PITCH (means that font is fixed-width) that can be used as a bit mask for lfPitchAndFamily.
您需要分析LOGFONT.lfPitchAndFamily成员的2个最低位。有一个常量FIXED_PITCH(表示字体是固定宽度),可用作lfPitchAndFamily的位掩码。
Here is a useful article:
这是一篇有用的文章:
枚举字体
Enumerating fonts can be a little confusing, and unless you want to enumerate all fonts on your system, can be a little more difficult than MSDN suggests. This article will explain exactly the steps you need to use to find every fixed-width font on your system, and also enumerate every possible size for each individual font.
枚举字体可能有点令人困惑,除非你想枚举系统中的所有字体,否则比MSDN建议的要困难一些。本文将准确解释您在系统中查找每个固定宽度字体所需的步骤,并列出每种字体的每个可能大小。