How to query NATIVE hardware resolution of primary monitor in Windows?

不羁的心 提交于 2019-12-03 08:35:38

Decided to give up talking directly to the monitor and instead parsing EDID information cached in the registry. This code isn't perfect, but it works:

import win32api as api, win32con as con, pywintypes
import win32com.client
_objWMIService = win32com.client.Dispatch('WbemScripting.SWbemLocator')
_objSWbemServices = _objWMIService.ConnectServer('.', 'root\\cimv2')
wmiquery = _objSWbemServices.ExecQuery

# get_regval(regkey) is simple registry reading function.
def get_monitor_res():
    dtd = 54  # start byte of detailed timing desc.

    try:  # get PNP id to find EDID in registry
        for monitor in wmiquery('Select * from Win32_DesktopMonitor'):
            # http://msdn.microsoft.com/en-us/library/aa394122%28VS.85%29.aspx
            if monitor.Availability in (3, 7, 13, 14, 15, 16): # connected
                curres = (monitor.ScreenWidth, monitor.ScreenHeight)
                print 'DEBUG: Current monitor resolution from WMI: %s' % (curres,)
                regkey = ('HKLM\\SYSTEM\\CurrentControlSet\\Enum\\' +
                    monitor.PNPDeviceID + '\\Device Parameters\\EDID')
                edid = get_regval(regkey)
                if edid:
                    print 'DEBUG: EDID Version: %s.%s' % (edid[18], edid[19])
                    # upper nibble of byte x 2^8 combined with full byte
                    hres = ((edid[dtd+4] >> 4) << 8) | edid[dtd+2]
                    vres = ((edid[dtd+7] >> 4) << 8) | edid[dtd+5]
                    print 'DEBUG: EDID DTD0: ' + str((hres, vres))
                    res = (hres, vres)
                    break  # give up on first success
                else:
                    raise RuntimeError, 'EDID not found in registry'
    except (RuntimeError, Exception) as err:
        print 'ERROR: %s.' % err

    return res
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!