.Net枚举winforms字体样式?

2023-11-27

我一直在寻找一种使用 .Net 框架列出给定字体的有效字体样式的方法(即使我必须 pinvoke gdi32 或其他一些 API),因为并非所有字体都属于 System.Drawing.FontStyle 枚举值(粗体、斜体、常规、删除线、下划线)。不符合要求的字体的一个完美示例是 Segoe UI,它是 TrueType Microsoft 字体,字体样式为:Regular、Semibold、Light、Bold、Italic 和 BoldItalic。另一个例子是 Arial,它有:常规、窄体、斜体、粗体、粗斜体、窄粗体、窄粗斜体和窄斜体。

在 Windows 7 中(也可能是 Vista,但我没有机器可以检查),当您打开资源管理器并浏览到 %SystemRoot%\Fonts 时,您将看到一个名为“字体样式”的列,其中列出了所有可用的样式对于每种字体,这告诉我肯定有一种方法可以做到这一点,至少通过 API 调用。

最终,我希望枚举 FontFamily 列表,然后列出每个系列的每种字体样式。下面是列出所有字体系列的示例代码,如果有人可以提供帮助列出每个系列可用的字体样式,我将不胜感激。如果我的做法是错误的,我绝对愿意接受建议。

Drawing.Text.InstalledFontCollection ifc = new Drawing.Text.InstalledFontCollection();
foreach ( FontFamily ff in ifc.Families )
{
    Console.WriteLine(ff.ToString());
    // Something like this would be nice, but AFAIK nothing similar exists
    /*
    foreach ( FontStyle style in ff.Styles )
        Console.WriteLine(style.ToString());
    */
}

好的,下面将有很多代码。主要是因为 TTF 结构和 TTF 文件的字节顺序。该代码最初不是我的,它来自一些来源,我已将其移植到 VB.NET 并更改了一些内容。看这一页对于获取字体名称的 C++ 版本。

此代码读取已安装字体的注册表(无论是在 %windir%\fonts 还是其他地方),过滤以仅获取具有 .ttf 扩展名的字体(例如 .fon 和 .ttc 被忽略),然后将这些字体文件路径传递给例行公事,GetFontDetails,读取并获取字体名称 (uNameID #1) 和字体子系列(又名样式,uNameID #2)。如果您有兴趣获得更多房产,请访问name - 命名表在 Microsoft 的 Typography 网站上并在浏览器中搜索Name IDs。然后它将字体名称、字体子系列和字体路径踢出到控制台窗口。

Create a new VB.NET Console app and paste the below in over Module1 code and press F5.

无需再费周折:

Imports System.Linq
Imports System.IO
Imports System.Text

Module Module1
    Sub Main()
        Dim allInstalledFonts = From e In My.Computer.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts").GetValueNames
                                 Select My.Computer.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts").GetValue(e)
        Dim ttfFonts = From e In allInstalledFonts.Where(Function(e) e.ToString.EndsWith(".ttf") Or e.ToString.EndsWith(".otf"))
        Dim ttfFontsPaths = From e In ttfFonts.Select(Function(e) If(Path.GetPathRoot(e.ToString) = "", Environment.GetFolderPath(Environment.SpecialFolder.Fonts) & "\" & e.ToString, e.ToString))
        Dim fonts = From e As String In ttfFontsPaths Select GetFontDetails(e.ToString)

        For Each f As InstalledFont In fonts
            Console.WriteLine("Name: " & f.FontName & ", SubFamily: " & f.FontSubFamily & ", Path: " & f.FontPath)
        Next
        Console.ReadLine()
    End Sub
    Public Class InstalledFont
        Property FontName As String
        Property FontSubFamily As String
        Property FontPath As String
        Sub New(ByVal name As String, ByVal subfamily As String, ByVal path As String)
            FontName = name
            FontSubFamily = subfamily
            FontPath = path
        End Sub
    End Class
    Public Function GetFontDetails(ByVal fontFilePath As String) As InstalledFont
        Dim FontName As String = String.Empty
        Dim FontSubFamily As String = String.Empty
        Dim encStr = "UTF-8"
        Dim strRet As String = String.Empty

        Using fs As New FileStream(fontFilePath, FileMode.Open, FileAccess.Read)
            Dim ttOffsetTable As New TT_OFFSET_TABLE
            With ttOffsetTable
                .uMajorVersion = ReadUShort(fs)
                .uMinorVersion = ReadUShort(fs)
                .uNumOfTables = ReadUShort(fs)
                .uSearchRange = ReadUShort(fs)
                .uEntrySelector = ReadUShort(fs)
                .uRangeShift = ReadUShort(fs)
            End With

            If ttOffsetTable.uMajorVersion <> 1 Or ttOffsetTable.uMinorVersion <> 0 Then
                Return Nothing
            End If

            Dim tblDir As New TT_TABLE_DIRECTORY
            Dim found As Boolean = False

            For i As Integer = 0 To ttOffsetTable.uNumOfTables
                With tblDir
                    .Initialize()
                    fs.Read(.szTag, 0, .szTag.Length)
                    .uCheckSum = ReadULong(fs)
                    .uOffset = ReadULong(fs)
                    .uLength = ReadULong(fs)
                End With

                Dim enc As Encoding = Encoding.GetEncoding(encStr)

                Dim s As String = enc.GetString(tblDir.szTag)
                If StrComp(s, "name") = 0 Then
                    found = True
                    Exit For
                End If
            Next

            If Not found Then Return Nothing

            fs.Seek(tblDir.uOffset, SeekOrigin.Begin)
            Dim ttNTHeader As New TT_NAME_TABLE_HEADER
            With ttNTHeader
                .uFSelector = ReadUShort(fs)
                .uNRCount = ReadUShort(fs)
                .uStorageOffset = ReadUShort(fs)
            End With

            Dim ttRecord As New TT_NAME_RECORD

            For j As Integer = 0 To ttNTHeader.uNRCount
                With ttRecord
                    .uPlatformID = ReadUShort(fs)
                    .uEncodingID = ReadUShort(fs)
                    .uLanguageID = ReadUShort(fs)
                    .uNameID = ReadUShort(fs)
                    .uStringLength = ReadUShort(fs)
                    .uStringOffset = ReadUShort(fs)
                End With

                If ttRecord.uNameID > 2 Then Exit For

                Dim nPos As Integer = fs.Position
                fs.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, SeekOrigin.Begin)

                Dim buf(ttRecord.uStringLength - 1) As Byte
                fs.Read(buf, 0, ttRecord.uStringLength)

                Dim enc As Encoding
                If ttRecord.uEncodingID = 3 Or ttRecord.uEncodingID = 1  Then
                    enc = Encoding.BigEndianUnicode
                Else
                    enc = Encoding.UTF8
                End If

                strRet = enc.GetString(buf)
                If ttRecord.uNameID = 1 Then FontName = strRet
                If ttRecord.uNameID = 2 Then FontSubFamily = strRet
                fs.Seek(nPos, SeekOrigin.Begin)
            Next
            Return New InstalledFont(FontName, FontSubFamily, fontFilePath)
        End Using
    End Function
    Public Structure TT_OFFSET_TABLE
        Public uMajorVersion As UShort
        Public uMinorVersion As UShort
        Public uNumOfTables As UShort
        Public uSearchRange As UShort
        Public uEntrySelector As UShort
        Public uRangeShift As UShort
    End Structure
    Public Structure TT_TABLE_DIRECTORY
        Public szTag() As Byte
        Public uCheckSum As UInt32
        Public uOffset As UInt32
        Public uLength As UInt32
        Public Sub Initialize()
            ReDim szTag(3)
        End Sub
    End Structure
    Public Structure TT_NAME_TABLE_HEADER
        Public uFSelector As UShort
        Public uNRCount As UShort
        Public uStorageOffset As UShort
    End Structure
    Public Structure TT_NAME_RECORD
        Public uPlatformID As UShort
        Public uEncodingID As UShort
        Public uLanguageID As UShort
        Public uNameID As UShort
        Public uStringLength As UShort
        Public uStringOffset As UShort
    End Structure
    Private Function ReadChar(ByRef fs As FileStream, ByVal characters As Integer) As UInt16
        Dim s(characters) As String
        Dim buf(CByte(s.Length)) As Byte
        buf = ReadAndSwap(fs, buf.Length)
        Return BitConverter.ToUInt16(buf, 0)
    End Function
    Private Function ReadByte(ByRef fs As FileStream) As UInt16
        Dim buf(10) As Byte
        buf = ReadAndSwap(fs, buf.Length)
        Return BitConverter.ToUInt16(buf, 0)
    End Function
    Private Function ReadUShort(ByRef fs As FileStream) As UInt16
        Dim buf(1) As Byte
        buf = ReadAndSwap(fs, buf.Length)
        Return BitConverter.ToUInt16(buf, 0)
    End Function
    Private Function ReadULong(ByRef fs As FileStream) As UInt32
        Dim buf(3) As Byte
        buf = ReadAndSwap(fs, buf.Length)
        Return BitConverter.ToUInt32(buf, 0)
    End Function
    Private Function ReadAndSwap(ByRef fs As FileStream, ByVal size As Integer) As Byte()
        Dim buf(size - 1) As Byte
        fs.Read(buf, 0, buf.Length)
        Array.Reverse(buf)
        Return buf
    End Function
End Module
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net枚举winforms字体样式? 的相关文章

  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 使用 %d 打印 unsigned long long

    为什么我打印以下内容时得到 1 unsigned long long int largestIntegerInC 18446744073709551615LL printf largestIntegerInC d n largestInte
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中

随机推荐

  • 实现“show”函数

    我想实施show 二元 函数的方法并使其能够区分内函子 a gt a 类似于伪 Haskell 代码 instance Show a gt b where show fun lt
  • jquery:如何更新可拖动克隆ID?

    我想将可拖动项目添加到可排序列表中 这在我的示例中运行良好http jsbin com ipese5 35 问题是我想在拖动到可排序列表时更新克隆项目的 id 奇怪的是 下面的代码将 de ui 对象中的 id 更新为 new id 正如我
  • 将 RTF 文本从数据库加载到 TRichEdit

    我目前正在将我们的软件解决方案从 Delphi 7 迁移到 2010 大部分更改都很简单 只剩下少量障碍 在表单上 我们使用 TRichEdit 它显示从 MSSQL 数据库中的 blob 字段抓取的 rtf 文本 Delphi 7 中是这
  • 如何在常规管道作业中触发多分支管道 Jenkins 作业?

    我想触发特定的多分支管道作业 maven 发布 工作流程 测试 特定分支 在常规管道作业中 是否有我需要指定的特殊 build 命令模式 代码片段生成器仅打印 没有这样的工作 maven release workflow test 通过反复
  • 根据元素在另一个已排序列表中的位置对 python 中的列表进行排序

    我想根据预先排序的列表对 Python 中的列表进行排序 presorted list 2C 3C 4C 2D 3D 4D unsorted list 3D 2C 4D 2D 我该如何排序unsorted list使得这些值以相同的顺序出现
  • Angular 6 HTML选择菜单设置默认值

    我习惯了旧的 AngularJS 方式来选择菜单和选择默认值等 但我很难理解如何在 Angular 中执行此操作 6 我有一系列菜单项 fontChoices label Trebuchet value Trebuchet MS Helve
  • Updatepanel 提供完整回发而不是异步回发

    我遇到了一个似乎非常著名的问题 我的 updatepanel 触发完整回发而不是异步回发 正常的解决方案是为所有动态添加的控件提供一个 ID 我已经这样做了 但我仍然得到完整的回发而不是异步回发 这是代码 HTML
  • 如何在 matplotlib 中绘制 3D 旋转图?

    假设您有一条 2D 曲线 例如 from matplotlib import pylab t numpy linspace 1 1 21 z t 2 pylab plot t z 产生 我想进行一场革命来实现 3d 绘图 参见http re
  • 如何在Android项目中使用ThreeTenABP

    我使用的是 Android Studio 2 1 2 我的 Java 设置如下 gt java version gt openjdk version 1 8 0 91 gt OpenJDK Runtime Environment build
  • Linq to Entities 中的动态 where 子句

    我正在使用 linq toEntity EF 我有一个带有 4 个字符串参数的构造函数 根据哪个参数不为空 我必须构建 linq 查询 我可以使用 if else 语句 但我还有其他带有 10 个参数的构造函数 在这种情况下 将会有很多组合
  • 在 SQL Server 上逐字使用 SOUNDEX()

    这是我的问题 例如我有一张桌子Products包含一个字段 Name Products ID Name 1 USB Key 10Go 2 Intel computer 3 12 inches laptop computer 我目前正在为 i
  • C# 中的 FlowDocument 内存问题

    我目前正在尝试解决释放 FlowDocument 资源的问题 我正在加载一个 rtf 文件并使用 TextRange Load 将其放入 FlowDocument 中 我注意到 在执行此操作后 它会保留这些资源 并且 GC 不会收集它 我运
  • 控制台应用程序中的 Twitter OAuth

    是否可以在不访问身份验证网页的情况下对 Twitter 控制台应用程序进行授权 我需要它 因为我正在开发可以从我们公司 Twitter 获取直接消息的应用程序 该控制台应用程序安排在 Web 服务器上 而不是由人类驱动 问候 阿列克谢 扎哈
  • 如何在 nhibernate 中复制和重试死锁

    查看我的日志 我可以看到我的应用程序很容易出现死锁 它们出现在我的应用程序的许多部分 1 有没有办法复制这个问题 即 我只在日志中看到过这一点 2 如果事务被锁定 重试的最佳 最简单方法是什么 3 如果我将调用包装在 try catch 中
  • 如何指定属性必须是(比如说)整数列表,而不仅仅是列表?

    使用属性库和 Python 3 6 我认为以下内容可以让我指定x and y只能包含整数 import attr attr s class C x List int attr ib not working y attr ib type Li
  • 内存目标 BTS 为何会比 load / BTS reg,reg / store 慢得多?

    在一般情况下 可以使用内存或寄存器操作数的指令如何会比内存操作数慢 mov mov gt 指令 gt mov mov 基于发现的吞吐量和延迟Agner Fog 的说明书 以我为例 查看 Skylake p238 我看到以下数字btr bts
  • Resharper 格式化链式方法

    R 中是否有设置将链接方法格式化为从实例化类的相同字符开始 我想要的是 var foo new FooDataBuilder WithDate myDate WithBar myBar Build R 给了我什么 var foo new F
  • 如何在 Windows 中注册自定义 URL 协议?

    如何向 Windows 注册自定义协议 以便在单击电子邮件或网页中的链接时打开我的应用程序并将 URL 中的参数传递给它 Go to Start然后在Find type regedit gt 它应该打开注册表编辑器 Click Right
  • ASP.NET MVC 获取视图的最后修改日期/文件信息

    我需要在工作申请的每一页上注明最后修改日期 我曾经通过在 WebForms 母版页底部包含对 的引用来实现此目的 该引用将返回当前 aspx 页面的上次修改日期 我的代码甚至会检查关联的 aspx cs 文件 比较上次修改日期 并返回最近的
  • .Net枚举winforms字体样式?

    我一直在寻找一种使用 Net 框架列出给定字体的有效字体样式的方法 即使我必须 pinvoke gdi32 或其他一些 API 因为并非所有字体都属于 System Drawing FontStyle 枚举值 粗体 斜体 常规 删除线 下划