Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 52 lines
 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 .

1 comment

Scott Stafford 18 years, 5 months ago  # | flag

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.

class RECT(ctypes.Structure):
  _fields_ = [
    ('left', ctypes.c_long),
    ('top', ctypes.c_long),
    ('right', ctypes.c_long),
    ('bottom', ctypes.c_long)
    ]