代码之家  ›  专栏  ›  技术社区  ›  Spencer

python windows枚举安装的字体

  •  2
  • Spencer  · 技术社区  · 6 年前

    我正在尝试获取Windows计算机上已安装字体的列表,以便安装丢失的字体。我在PY3.*上,Windows 7。

    透过 win API 我知道需要使用的文档 EnumFontFamiliesExW 但是,我不确定Python中的ctypes的正确语法是什么…我对ctypes模块完全陌生,对c不太了解。ctypes的python文档对我来说非常难理解,所以如果我在那里找不到这个答案,我很抱歉(我确实看了一下)。

    我查到了以下几点:

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

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   Barmak Shemirani    6 年前

    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 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))
    

    EnumFontFamiliesExW