2010-12-01 11 views
6

Necesito encontrar la "mejor" o resolución nativa para un monitor LCD adjunto en Windows (que luego estableceré programáticamente y sabré cómo hacerlo). Permítanme repetir que no necesito la resolución actual de Windows, ni necesito preocuparse por los CRT/proyectores.¿Cómo consultar la resolución de hardware NATIVE del monitor principal en Windows?

que he visto trabajar con este programa, así que sé que es posible a pesar de los detractores: http://www.entechtaiwan.com/util/moninfo.shtm

Sería mejor hablar directamente al monitor y consultar la información EDID. Sin embargo, he visto que está almacenado en caché en el registro y que no tendría problemas para desenterrarlo de HKLM \ SYSTEM \ CurrentControlSet \ Enum \ DISPLAY, pero no puede encontrar la manera de unir los datos con el monitor principal actual.

Lo que encontrar este programa en C: http://www.tech-archive.net/Archive/Development/microsoft.public.development.device.drivers/2004-08/0294.html y un programa Python similar: http://www.koders.com/python/fid7FCCE3C908F376DC62F06CAD9B11C6D7C1CFA78F.aspx

Por desgracia, estoy teniendo un montón de problemas para convertir el programa C a pitón, como el código correspondiente doesn' Parece que está en los módulos de win32all. Intenté compilarlo, pero no tengo espacio en disco para un compilador grande y no he usado C por años. Estoy un poco fuera de mi elemento con ctypes también.

Mi plan B utilizará EnumDisplaySettings() para encontrar el valor más grande para la resolución y configurarlo para eso. En la PC que he probado, da las res correctas, pero aún podría ser problemático.

Preferiría una solución en python, pero tal vez alguien podría ayudarme a modificar el programa C para escupir la resolución y compilarla. Gracias por adelantado.

Actualización:

He encontrado una posible solución. Ahora estoy leyendo WMI para encontrar un monitor que esté disponible (no fuera de línea), tomando su identificación de dispositivo PNP y leyendo EDID del registro en la subclave con el valor de identificación. Luego analizo los datos para los bytes 38 y 39 y los calculo. No muy limpio, pero estoy obteniendo resultados. Si esta es una forma razonable de hacerlo, cerraré esta pregunta, gracias.

+0

También hay compiladores bastante pequeños, como Pelles C y DevCpp. –

+0

Es bueno saberlo, gracias. –

+0

No cierre la pregunta, responda a sí mismo en una nueva respuesta. Mañana incluso podrías aceptar tu propia respuesta si quieres. Esto fue interesante –

Respuesta

2

Decidió dejar de hablar directamente con el monitor y, en su lugar, analizar la información EDID en caché en el registro. Este código no es perfecto, pero funciona:

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 
+0

¿En qué biblioteca está 'wmiquery'? Parece que no puedo encontrarlo. – soren121

+0

Lo siento, tratando de extraer de mi código, dejé una parte o dos. Ese es un nombre que creé porque los nombres de API son tan horribles. Agregar ahora –

Cuestiones relacionadas