Как запросить аппаратное разрешение NATIVE основного монитора в Windows? - PullRequest
6 голосов
/ 01 декабря 2010

Мне нужно найти «лучшее» или собственное разрешение для подключенного ЖК-монитора под Windows (которое я затем установлю программно и знаю, как это сделать). Позвольте мне повторить, что мне не нужно ни текущее разрешение Windows, ни надо беспокоиться о ЭЛТ / проекторах.

Я видел, как она работает с этой программой, поэтому я знаю, что это возможно, несмотря на скептиков: http://www.entechtaiwan.com/util/moninfo.shtm

Лучше всего поговорить напрямую с монитором и запросить информацию EDID. Однако я видел, что он кешируется в реестре и у него не возникнет проблем с извлечением его из HKLM \ SYSTEM \ CurrentControlSet \ Enum \ DISPLAY, но я не могу понять, как сопоставить данные с текущим основным монитором.

Я нашел эту программу на C: http://www.tech -archive.net / Архив / Разработка / microsoft.public.development.device.drivers / 2004-08 / 0294.html и аналогичная программа на Python: http://www.koders.com/python/fid7FCCE3C908F376DC62F06CAD9B11C6D7C1CFA78F.aspx

К сожалению, у меня много проблем с преобразованием C-программы в python, так как соответствующий код, похоже, отсутствует в модулях win32all. Я бы попытался скомпилировать его, но у меня не было места на диске для большого компилятора, и я не использовал C годами. Я немного не в себе с ctypes.

Мой план B будет заключаться в том, чтобы использовать EnumDisplaySettings (), чтобы найти наибольшее значение для разрешения и установить его равным этому. На компьютерах, которые я пробовал, он дает правильное разрешение, но это все еще может быть проблематичным.

Я бы предпочел решение на python, но, возможно, кто-то мог бы помочь мне изменить программу на C, чтобы выложить разрешение и скомпилировать его. Заранее спасибо.

Обновление:

Я нашел потенциальное решение. Сейчас я читаю WMI, чтобы найти монитор, который доступен (не в автономном режиме), захватывает его идентификатор устройства PNP и считывает EDID из реестра в подразделе со значением id. Затем я анализирую данные для байтов 38 и 39 и вычисляю. Не очень чисто, но я получаю результаты. Если это разумный способ сделать это, я закрою этот вопрос, спасибо.

1 Ответ

2 голосов
/ 18 декабря 2010

Решили прекратить говорить напрямую с монитором и вместо этого анализировать информацию 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...