This recipe gets the sizes of all the monitors on a multi-monitor Windows PC. It gets both the actual resolution and the usable ("work") resolutions. The usable resolution excludes the taskbar and docked applications.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import ctypes
user = ctypes.windll.user32
class RECT(ctypes.Structure):
_fields_ = [
('left', ctypes.c_ulong),
('top', ctypes.c_ulong),
('right', ctypes.c_ulong),
('bottom', ctypes.c_ulong)
]
def dump(self):
return map(int, (self.left, self.top, self.right, self.bottom))
class MONITORINFO(ctypes.Structure):
_fields_ = [
('cbSize', ctypes.c_ulong),
('rcMonitor', RECT),
('rcWork', RECT),
('dwFlags', ctypes.c_ulong)
]
def get_monitors():
retval = []
CBFUNC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(RECT), ctypes.c_double)
def cb(hMonitor, hdcMonitor, lprcMonitor, dwData):
r = lprcMonitor.contents
#print "cb: %s %s %s %s %s %s %s %s" % (hMonitor, type(hMonitor), hdcMonitor, type(hdcMonitor), lprcMonitor, type(lprcMonitor), dwData, type(dwData))
data = [hMonitor]
data.append(r.dump())
retval.append(data)
return 1
cbfunc = CBFUNC(cb)
temp = user.EnumDisplayMonitors(0, 0, cbfunc, 0)
#print temp
return retval
def monitor_areas():
retval = []
monitors = get_monitors()
for hMonitor, extents in monitors:
data = [hMonitor]
mi = MONITORINFO()
mi.cbSize = ctypes.sizeof(MONITORINFO)
mi.rcMonitor = RECT()
mi.rcWork = RECT()
res = user.GetMonitorInfoA(hMonitor, ctypes.byref(mi))
data.append(mi.rcMonitor.dump())
data.append(mi.rcWork.dump())
retval.append(data)
return retval
print monitor_areas()
|
This recipe requires ctypes from http://starship.python.net/crew/theller/ctypes .
Tags: ui
Negative RECT values. My dual monitor setup includes a primary monitor to the right of the secondary. This causes negative numbers for RECT.top and/or RECT.left, which the functions above casted as c_ulong. Using c_long's corrects this glitch.