如何在Windows中查询主监视器的NATIVE硬件解析?

Gri*_*ave 6 c python windows resolution monitor

我需要在Windows下为附加的LCD显示器找到"最佳"或原生分辨率(然后我将以编程方式设置并知道该怎么做.)让我再说一遍,我不需要当前的Windows分辨率,也不必担心关于CRT /投影仪.

我已经看到它与这个程序一起工作,所以我知道尽管反对者有可能:http: //www.entechtaiwan.com/util/moninfo.shtm

最好直接与监视器对话并查询EDID信息.但是,我已经看到它被缓存在注册表中并且从HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY中挖出它不会有问题,但无法弄清楚如何将数据与当前主监视器匹配.

我确实找到了这个C程序:http: //www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2004-08/0294.html 和类似的python程序: http:/ /www.koders.com/python/fid7FCCE3C908F376DC62F06CAD9B11C6D7C1CFA78F.aspx

不幸的是,我在将C程序转换为python时遇到了很多麻烦,因为相关代码似乎不在win32all模块中.我尝试编译它,但没有大型编译器的磁盘空间,并且多年没有使用过C.对于ctypes我也有点偏离我的元素.

我的计划B将使用EnumDisplaySettings()来找到最大的分辨率值并将其设置为.在PC上我试过它给出了正确的res,但它仍然可能有问题.

我更喜欢python中的解决方案,但也许有人可以帮我修改C程序以吐出分辨率并编译它.提前致谢.

更新:

我找到了一个潜在的解决方案.我现在正在阅读WMI以找到可用的监视器(不是脱机),获取其PNP设备ID,并从子目录中的注册表中读取具有id值的EDID.然后我解析字节38和39的数据并计算.不是很干净,但我得到的结果.如果这是一个合理的方法,我会关闭这个问题,谢谢.

Gri*_*ave 2

决定放弃直接与显示器对话,而是解析缓存在注册表中的 EDID 信息。这段代码并不完美,但它可以工作:

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
Run Code Online (Sandbox Code Playgroud)