如何在Windows中查询主监视器的NATIVE硬件分辨率?

我需要find在Windows下连接的液晶显示器的“最佳”或本机分辨率(然后我将设置程序并知道如何操作。)让我重申一下,我不需要当前的Windows分辨率,也不需要担心关于CRT /投影仪。

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

最好直接与显示器对话并查询EDID信息。 但是,我已经看到,它被caching在registry中,并不会从HKLM \ SYSTEM \ CurrentControlSet \ Enum \ DISPLAY中挖出问题,但无法弄清楚如何将数据与当前的主监视器进行匹配。

我find了这个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()来find最大的分辨率值并将其设置为。 在PC上,我试过它给出了正确的资源,但它仍然可能是有问题的。

我更喜欢Python的解决scheme,但也许有人可以帮助我修改C程序吐出解决scheme并编译它。 提前致谢。

更新:

我find了一个潜在的解决scheme。 我正在阅读WMI来查找可用(不是离线)的监视器,抓取它的PNP设备ID,并从registry中读取具有id值的子项的EDID。 然后我parsing字节38和39的数据并计算。 不是很干净,但正在得到的结果。 如果这是一个合理的做法,我会closures这个问题,谢谢。

决定放弃直接与监视器通话,而是解析缓存在注册表中的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