我正在尝试通过 Windows API 的EnumDisplayMonitors枚举可用的显示监视器。但是,我遇到了一些我无法弄清楚的非常奇怪的行为。也就是说,该函数可以正确运行,但前提是它不在函数内部。
如果我像这样将它放在模块级别:
模块代码
def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData
if __name__ == '__main__':
# Callback Factory
MonitorEnumProc = WINFUNCTYPE(
ctypes.c_bool,
ctypes.wintypes.HMONITOR,
ctypes.wintypes.HDC,
ctypes.POINTER(RECT),
ctypes.wintypes.LPARAM
)
# Make the callback function
enum_callback = MonitorEnumProc(_monitorEnumProc)
# Enumerate the windows
print 'return code: %d' % windll.user32.EnumDisplayMonitors(
None,
None,
enum_callback,
0
)
一切都按预期运行。它为我的两个连接的显示器打印出handles
和。rects
输出:
>>> call result: 65537 None <__main__.LP_RECT object at 0x02250EE0> 0
>>> call result: 65539 None <__main__.LP_RECT object at 0x02250EE0> 0
[Finished in 0.1s]
一切都很好。该EnumDisplayMonitors
函数返回一个非零值,表明一切都按计划进行。
现在,问题来了,如果我将完全相同的代码粘贴到一个函数中,事情就会变得很糟糕。
功能码
def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData
def enum_mons():
# Callback Factory
MonitorEnumProc = WINFUNCTYPE(
ctypes.c_bool,
ctypes.wintypes.HMONITOR,
ctypes.wintypes.HDC,
ctypes.POINTER(RECT),
ctypes.wintypes.LPARAM
)
# Make the callback function
enum_callback = MonitorEnumProc(_monitorEnumProc)
# Enumerate the windows
print 'return code: %d' % windll.user32.EnumDisplayMonitors(
None,
None,
enum_callback,
0
)
if __name__ == '__main__':
enum_mons()
所以,完全相同的代码,除了现在在函数内部。
输出
call result: 65537 None <__main__.LP_RECT object at 0x02250E90> 0
0
它不会吐出所有连接的监视器和成功代码,而是仅吐出一个监视器和一个 0,根据MSDN 文档,这意味着函数失败。
有谁知道是什么原因造成的?这让我很难过!