<p>我想首先指出:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/52268294/python-ctypes-cdll-loadlibrary-instantiate-an-object-execute-its-method-priva/52272969#52272969">[SO]: Python ctypes cdll.LoadLibrary, instantiate an object, execute its method, private variable address truncated
(@CristiFati's answer)</a></li>
<li><a href="https://stackoverflow.com/questions/53182796/python-ctypes-issue-on-different-oses/53185316#53185316">[SO]: python ctypes issue on different OSes (@CristiFati's answer)</a></li>
</ul>
<p>ctypes</em>页面(也列在上面的URL</em>s中):<a href="https://docs.python.org/3/library/ctypes.html#module-ctypes" rel="nofollow noreferrer">[Python 3.Docs]: ctypes - A foreign function library for Python</a></p>
<p>我把你的密码改了一点。在</p>
<p><em>代码.py</em>:</p>
<pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python
import sys
from ctypes import POINTER, WinDLL, Structure, sizeof, byref
from ctypes.wintypes import BOOL, SHORT, WCHAR, UINT, ULONG, DWORD, HANDLE
LF_FACESIZE = 32
STD_OUTPUT_HANDLE = -11
class COORD(Structure):
_fields_ = [
("X", SHORT),
("Y", SHORT),
]
class CONSOLE_FONT_INFOEX(Structure):
_fields_ = [
("cbSize", ULONG),
("nFont", DWORD),
("dwFontSize", COORD),
("FontFamily", UINT),
("FontWeight", UINT),
("FaceName", WCHAR * LF_FACESIZE)
]
kernel32_dll = WinDLL("kernel32.dll")
get_last_error_func = kernel32_dll.GetLastError
get_last_error_func.argtypes = []
get_last_error_func.restype = DWORD
get_std_handle_func = kernel32_dll.GetStdHandle
get_std_handle_func.argtypes = [DWORD]
get_std_handle_func.restype = HANDLE
get_current_console_font_ex_func = kernel32_dll.GetCurrentConsoleFontEx
get_current_console_font_ex_func.argtypes = [HANDLE, BOOL, POINTER(CONSOLE_FONT_INFOEX)]
get_current_console_font_ex_func.restype = BOOL
set_current_console_font_ex_func = kernel32_dll.SetCurrentConsoleFontEx
set_current_console_font_ex_func.argtypes = [HANDLE, BOOL, POINTER(CONSOLE_FONT_INFOEX)]
set_current_console_font_ex_func.restype = BOOL
def main():
# Get stdout handle
stdout = get_std_handle_func(STD_OUTPUT_HANDLE)
if not stdout:
print("{:s} error: {:d}".format(get_std_handle_func.__name__, get_last_error_func()))
return
# Get current font characteristics
font = CONSOLE_FONT_INFOEX()
font.cbSize = sizeof(CONSOLE_FONT_INFOEX)
res = get_current_console_font_ex_func(stdout, False, byref(font))
if not res:
print("{:s} error: {:d}".format(get_current_console_font_ex_func.__name__, get_last_error_func()))
return
# Display font information
print("Console information for {:}".format(font))
for field_name, _ in font._fields_:
field_data = getattr(font, field_name)
if field_name == "dwFontSize":
print(" {:s}: {{X: {:d}, Y: {:d}}}".format(field_name, field_data.X, field_data.Y))
else:
print(" {:s}: {:}".format(field_name, field_data))
while 1:
try:
height = int(input("\nEnter font height (invalid to exit): "))
except:
break
# Alter font height
font.dwFontSize.X = 10 # Changing X has no effect (at least on my machine)
font.dwFontSize.Y = height
# Apply changes
res = set_current_console_font_ex_func(stdout, False, byref(font))
if not res:
print("{:s} error: {:d}".format(set_current_console_font_ex_func.__name__, get_last_error_func()))
return
print("OMG! The window changed :)")
# Get current font characteristics again and display font size
res = get_current_console_font_ex_func(stdout, False, byref(font))
if not res:
print("{:s} error: {:d}".format(get_current_console_font_ex_func.__name__, get_last_error_func()))
return
print("\nNew sizes X: {:d}, Y: {:d}".format(font.dwFontSize.X, font.dwFontSize.Y))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
</code></pre>
<p><strong>注意事项</strong>:</p>
<ul>
<li><em>ctypes</em>允许类似于<em>C</em>的低级访问(只有语法是<em>Python</em>)</li>
<li>代码使用<a href="https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute" rel="nofollow noreferrer">[MS.Docs]: SetConsoleTextAttribute function</a>
<ul>
<li>为了避免设置无效值,它与对应的值一起使用:<a href="https://docs.microsoft.com/en-us/windows/console/getcurrentconsolefontex" rel="nofollow noreferrer">[MS.Docs]: GetCurrentConsoleFontEx function</a>。调用该函数以填充<em>CONSOLE_FONT_INFOEX</em>结构,然后只修改所需的值</li>
<li>有“更简单”的函数(例如<a href="https://docs.microsoft.com/en-us/windows/console/getcurrentconsolefont" rel="nofollow noreferrer">[MS.Docs]: GetCurrentConsoleFont function</a>或<a href="https://docs.microsoft.com/en-us/windows/console/getconsolefontsize" rel="nofollow noreferrer">[MS.Docs]: GetConsoleFontSize function</a>),但不幸的是没有相应的setter</li>
</ul></li>
<li>使用<code>ctypes.wintypes</code>常量(引用标准的<em>ctypes</em>类型)(给代码一种类似于<em>Win</em>的风格)</li>
<li>它非常(几乎痛苦地)长(也因为我添加了正确的错误处理)</li>
<li>另一种选择,如<a href="https://stackoverflow.com/questions/3592673/change-console-font-in-windows">[SO]: Change console font in Windows</a>(您从中复制代码)的一个答案中建议的,将是安装一个3<sup>rd</sup>方模块(例如<a href="https://github.com/mhammond/pywin32" rel="nofollow noreferrer">[GitHub]: mhammond/pywin32 - Python for Windows (pywin32) Extensions</a>,它是一个<em>Python</em>的包装器,覆盖了<em>WINAPI</em>s),这将需要更少的代码来编写,因为<em>Python</em>和<em>C</em>之间的桥接已经实现,而且上述功能可能只需几行代码就可以完成</li>
<li><p>正如我在代码中所评论的,设置<code>COORD.X</code>似乎被忽略了。但是当设置<code>COORD.Y</code>(设置为接近<code>COORD.Y // 2</code>的值-可能是为了保持纵横比)时,它会自动设置。在我的机器上(<em>Win 10x64</em>),默认值是<strong><em>16</em></strong>。你可能想在最后把它放回去,以避免让控制台处于“挑战”状态(显然,<em>Win</em>调整<em>cmd</em>窗口大小,与字体大小(某种程度上)同步):</p>
<p><a href="https://i.stack.imgur.com/H7VA6.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H7VA6.jpg" alt="PrintScreen"/></a></p></li>
</ul>