When you use a function, enum_callback
is getting deallocated when the Python frame for enum_mons
is garbage collected. So it's a race as to whether it still exists when Windows tries to call it for each monitor. Define the callback globally -- or use a class.
Also your callback should return True to continue the enumeration.
import ctypes
from ctypes import wintypes
LPRECT = ctypes.POINTER(wintypes.RECT)
# Callback Factory
MonitorEnumProc = ctypes.WINFUNCTYPE(
ctypes.c_bool,
wintypes.HMONITOR,
wintypes.HDC,
LPRECT,
wintypes.LPARAM)
ctypes.windll.user32.EnumDisplayMonitors.restype = wintypes.BOOL
ctypes.windll.user32.EnumDisplayMonitors.argtypes = [
wintypes.HDC,
LPRECT,
MonitorEnumProc,
wintypes.LPARAM]
def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData
print lprcMonitor[0].right, lprcMonitor[0].bottom
return True # continue enumeration
# Make the callback function
enum_callback = MonitorEnumProc(_monitorEnumProc)
def enum_mons():
'''Enumerate the display monitors.'''
return ctypes.windll.user32.EnumDisplayMonitors(
None,
None,
enum_callback,
0)
if __name__ == '__main__':
print 'return code: %d' % enum_mons()