【问题标题】:Python Windows Enum Installed FontsPython Windows 枚举安装字体
【发布时间】:2018-12-17 19:05:17
【问题描述】:

我正在尝试获取 Windows 机器上已安装字体的列表,以便我可以安装缺少的字体。我在 Py3.*,Windows 7 上。

查看win API 文档我知道我需要使用EnumFontFamiliesExW 但是我不确定python 中ctypes 的正确语法是什么...我对ctypes 模块完全陌生,不要我对 C 了解不多。ctypes 的 python 文档对我来说非常难以掌握,如果我无法在那里找到这个答案,很抱歉(我确实看过)。

我得到了以下几点:

gdi32 = ctypes.WinDLL('gdi32')
print(gdi32.EnumFontFamiliesExW())

这当然会引发错误,因为我没有指定任何参数。那么如何传递正确的参数呢?

【问题讨论】:

    标签: python python-3.x winapi fonts ctypes


    【解决方案1】:

    pywin32 扩展提供了一个更简单的选项。使用import win32gui,import win32api,...

    import win32gui
    
    def callback(font, tm, fonttype, names):
        names.append(font.lfFaceName)
        return True
    
    fontnames = []
    hdc = win32gui.GetDC(None)
    win32gui.EnumFontFamilies(hdc, None, callback, fontnames)
    print("\n".join(fontnames))
    win32gui.ReleaseDC(hdc, None)
    


    使用ctype,您必须了解 C 和 WinAPI。这是一个在 ctype 中执行此操作的示例,基于https://github.com/wwwtyro/AegisLuna/blob/master/pyglet/font/win32query.py
    import ctypes
    from ctypes import wintypes
    
    class LOGFONT(ctypes.Structure): _fields_ = [
        ('lfHeight', wintypes.LONG),
        ('lfWidth', wintypes.LONG),
        ('lfEscapement', wintypes.LONG),
        ('lfOrientation', wintypes.LONG),
        ('lfWeight', wintypes.LONG),
        ('lfItalic', wintypes.BYTE),
        ('lfUnderline', wintypes.BYTE),
        ('lfStrikeOut', wintypes.BYTE),
        ('lfCharSet', wintypes.BYTE),
        ('lfOutPrecision', wintypes.BYTE),
        ('lfClipPrecision', wintypes.BYTE),
        ('lfQuality', wintypes.BYTE),
        ('lfPitchAndFamily', wintypes.BYTE),
        ('lfFaceName', ctypes.c_wchar*32)]
    
    #we are not interested in NEWTEXTMETRIC parameter in FONTENUMPROC, use LPVOID instead
    FONTENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_int, 
        ctypes.POINTER(LOGFONT), wintypes.LPVOID, wintypes.DWORD, wintypes.LPARAM)
    
    fontlist = []
    def font_enum(logfont, textmetricex, fonttype, param):
        str = logfont.contents.lfFaceName;
        if (any(str in s for s in fontlist) == False):
            fontlist.append(str)
        return True
    
    hdc = ctypes.windll.user32.GetDC(None)
    ctypes.windll.gdi32.EnumFontFamiliesExW(hdc, None, FONTENUMPROC(font_enum), 0, 0)  
    ctypes.windll.user32.ReleaseDC(None, hdc)
    print("\n".join(fontlist))
    

    编辑:更改为 Unicode EnumFontFamiliesExW

    【讨论】:

    • 哇,谢谢!这比我想象的要复杂得多...尝试导入 win32gui 会在 py3 上引发错误,所以我猜这不再是标准模块了?虽然 Cypes 工作得很好,但我需要很长时间才能弄清楚这一切!有没有办法获取字体文件列表而不是系统字体名称?这会让我更容易比较。
    • 您可以获取 windows 字体目录(通常是 c:\windows\font,但并非总是如此),然后列出该目录中的所有文件。文件名可以是任何东西。最好尝试使用EnumFontFamiliesEx - pywin32 应该在版本 3 中可用,它是一个额外的扩展。
    • @BarmakShemirani 嘿,很抱歉打扰您,但我不知道如何正确获取文件名。
    猜你喜欢
    • 1970-01-01
    • 2017-06-09
    • 2013-11-15
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2015-08-08
    相关资源
    最近更新 更多