3

我正在尝试在 64 位 Windows 8 上使用 Python 获取默认控制台颜色:

class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
    _fields_ = [('dwSize', wintypes._COORD),
                ('dwCursorPosition', wintypes._COORD),
                ('wAttributes', c_ushort),
                ('srWindow', wintypes._SMALL_RECT),
                ('dwMaximumWindowSize', wintypes._COORD)]

...

def __init__(self):
        self.stdout_handle = windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE
        print self.stdout_handle # 28

        csbi   = CONSOLE_SCREEN_BUFFER_INFO()
        print sizeof(csbi) # 22
        retval = windll.kernel32.GetConsoleScreenBufferInfo(self.stdout_handle, byref(csbi))
        print windll.kernel32.GetLastError()
        print csbi.wAttributes, " (%s)" % bin(csbi.wAttributes)

        if retval == 0:
            formatwinerror() # A helper function

使用交互式解释器(导入和创建对象),使用 Python 2.7.5 失败,最后一个错误代码为 6(无效句柄)和属性 0。如果我运行相同的代码 Python 3.3.2,它可以工作(错误代码 0 和属性 0xf 是默认值)。有趣的是,如果我使用 Python 2.7.5 并改用以下代码,它可以工作:

import struct

...Same as before...

csbi = create_string_buffer(22)
retval = windll.kernel32.GetConsoleScreenBufferInfo(self.stdout_handle, csbi)
width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy = struct.unpack("hhhhHhhhhhh", csbi.raw)

print wattr, " (%s)" % bin(wattr)

...Same as before...

为了进行额外的调试,我将调用的核心复制到一个单独的脚本中(也在类外的一个函数中尝试过),现在它在两个版本的命令行上都能完美运行。但是,如果我在调用 GetStdHandle 之前添加此行,则 Python 2.7.5 的单独脚本将失败(来自此处),但使用交互式解释器仍然失败:

windll.kernel32.GetStdHandle.restype = wintypes.HANDLE

对于 Python 3.3.2,一切似乎都可以正常工作。我整晚都在搜索、阅读、查看其他 Python 模块并审查我的代码,但没有运气......到底发生了什么,我错过了什么?

4

1 回答 1

1

我没有考虑 Python 解释器是在哪种架构上编译的。

将该行添加windll.kernel32.GetConsoleScreenBufferInfo.argtypes = [wintypes.HANDLE, ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)]到我的代码后,它适用于我的所有解释器。我仍然无法解释为什么我的 Python 3.3.2 可以工作(64 位架构),但我猜 Python 3.x 的一些变化可能是原因。

于 2014-05-09T10:44:24.660 回答