Python Windows 枚举已安装的字体
Python Windows Enum Installed Fonts
我正在尝试获取 Windows 机器上已安装字体的列表,以便我可以安装缺少的字体。我在 Py3.*, Windows 7.
查看 win API 文档我知道我需要使用 EnumFontFamiliesExW
但是我不确定 python 中的 ctypes 的正确语法是什么......我'我是 ctypes 模块的新手,对 C 了解不多。ctypes 的 python 文档对我来说非常难以掌握,如果我在那里找不到这个答案,我深表歉意(我确实看过)。
我得到的结果如下:
gdi32 = ctypes.WinDLL('gdi32')
print(gdi32.EnumFontFamiliesExW())
这当然会引发错误,因为我没有指定任何参数。那么如何传递正确的参数呢?
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
我正在尝试获取 Windows 机器上已安装字体的列表,以便我可以安装缺少的字体。我在 Py3.*, Windows 7.
查看 win API 文档我知道我需要使用 EnumFontFamiliesExW
但是我不确定 python 中的 ctypes 的正确语法是什么......我'我是 ctypes 模块的新手,对 C 了解不多。ctypes 的 python 文档对我来说非常难以掌握,如果我在那里找不到这个答案,我深表歉意(我确实看过)。
我得到的结果如下:
gdi32 = ctypes.WinDLL('gdi32')
print(gdi32.EnumFontFamiliesExW())
这当然会引发错误,因为我没有指定任何参数。那么如何传递正确的参数呢?
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