¿Cómo obtener el tamaño físico correcto del monitor?

7 minutos de lectura

avatar de usuario
TipoDragón

¿Cómo puedo obtener el tamaño de la pantalla en centímetros o pulgadas?

Este código no siempre funciona correctamente:

HDC hdc = CreateDC(_T("DISPLAY"),dd.DeviceName,NULL,NULL);
int width = GetDeviceCaps(hdc, HORZSIZE);
int height = GetDeviceCaps(hdc, VERTSIZE);
ReleaseDC(0, hdc)

Especialmente para la configuración de varios monitores.

Actualizar: Necesito obtener el tamaño solo para monitores ordinarios, que tienen un tamaño físico constante.

avatar de usuario
TipoDragón

Encontré otra manera. El tamaño físico del monitor se almacena en el EDID, y Windows casi siempre tiene copias de su valor en el registro. Si puede analizar EDID, puede leer el ancho y el alto del monitor en centímetros.

Actualizar: Código agregado

BOOL GetMonitorDevice( TCHAR* adapterName, DISPLAY_DEVICE &ddMon )
{
    DWORD devMon = 0;

    while (EnumDisplayDevices(adapterName, devMon, &ddMon, 0))
    {
        if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE &&
            ddMon.StateFlags & DISPLAY_DEVICE_ATTACHED) // for ATI, Windows XP
            break;

        devMon++;
    }

    if (ddMon.DeviceString[0] == '\0')
    {
        EnumDisplayDevices(adapterName, 0, &ddMon, 0);
        if (ddMon.DeviceString[0] == '\0')
            _tcscpy_s(ddMon.DeviceString, _T("Default Monitor"));
    }
    return ddMon.DeviceID[0] != '\0';
}

BOOL GetMonitorSizeFromEDID(TCHAR* adapterName, DWORD& Width, DWORD& Height)
{
    DISPLAY_DEVICE ddMon;
    ZeroMemory(&ddMon, sizeof(ddMon));
    ddMon.cb = sizeof(ddMon);

    //read edid
    bool result = false;
    Width = 0;
    Height = 0;
    if (GetMonitorDevice(adapterName, ddMon))
    {
        TCHAR model[8];
        TCHAR* s = _tcschr(ddMon.DeviceID, '\\') + 1;
        size_t len = _tcschr(s, '\\') - s;
        if (len >= _countof(model))
            len = _countof(model) - 1;
        _tcsncpy_s(model, s, len);

        TCHAR *path = _tcschr(ddMon.DeviceID, '\\') + 1;
        TCHAR str[MAX_PATH] = _T("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\");
        _tcsncat_s(str, path, _tcschr(path, '\\')-path);
        path = _tcschr(path, '\\') + 1;
        HKEY hKey;
        if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, str, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
        {
            DWORD i = 0;
            DWORD size = MAX_PATH;
            FILETIME ft;
            while(RegEnumKeyEx(hKey, i, str, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
            {
                HKEY hKey2;
                if(RegOpenKeyEx(hKey, str, 0, KEY_READ, &hKey2) == ERROR_SUCCESS)
                {
                    size = MAX_PATH;
                    if(RegQueryValueEx(hKey2, _T("Driver"), NULL, NULL, (LPBYTE)&str, &size) == ERROR_SUCCESS)
                    {
                        if (_tcscmp(str, path) == 0)
                        {
                            HKEY hKey3;
                            if(RegOpenKeyEx(hKey2, _T("Device Parameters"), 0, KEY_READ, &hKey3) == ERROR_SUCCESS)
                            {
                                BYTE EDID[256];
                                size = 256;
                                if(RegQueryValueEx(hKey3, _T("EDID"), NULL, NULL, (LPBYTE)&EDID, &size) == ERROR_SUCCESS)
                                {
                                    DWORD p = 8;
                                    TCHAR model2[9];

                                    char byte1 = EDID[p];
                                    char byte2 = EDID[p+1];
                                    model2[0]=((byte1 & 0x7C) >> 2) + 64;
                                    model2[1]=((byte1 & 3) << 3) + ((byte2 & 0xE0) >> 5) + 64;
                                    model2[2]=(byte2 & 0x1F) + 64;
                                    _stprintf(model2 + 3, _T("%X%X%X%X"), (EDID[p+3] & 0xf0) >> 4, EDID[p+3] & 0xf, (EDID[p+2] & 0xf0) >> 4, EDID[p+2] & 0x0f);
                                    if (_tcscmp(model, model2) == 0)
                                    {
                                        Width = EDID[22];
                                        Height = EDID[21];
                                        result = true;
                                    }
                                    else
                                    {
                                        // EDID incorrect
                                    }
                                }
                                RegCloseKey(hKey3);
                            }
                        }
                    }
                    RegCloseKey(hKey2);
                }
                i++;
            }
            RegCloseKey(hKey);
        }
    }

    return result;
}

  • Un poco más de sangría estaría bien. Eso aseguraría que no pudiera ver las líneas completas en la pantalla de mi computadora de 30 ‘.

    – elíseo devorado

    30 de abril de 2010 a las 21:55

  • Además, es bueno tener en cuenta que no todos los monitores brindan información EDID.

    – Condez

    30 de abril de 2010 a las 22:12

  • Debe hacer algo razonable si el EDID no está allí. (No está en mi máquina). También debe tener en cuenta cosas como los proyectores, donde el tamaño de la imagen depende de la distancia de proyección, la configuración del zoom, etc.

    – Adrián McCarthy

    16/01/2015 a las 20:39

  • @KingDragon: Creo que hay algo de crédito en su lugar. ofekshilon.com/2014/06/19/reading-specific-monitor-dimensions

    – Ofek Shilón

    8 de noviembre de 2016 a las 16:52

  • No he probado para ejecutar este código, pero no creo que funcione en mi computadora. Simplemente devolvería los bytes 22 y 21, lo que no da las dimensiones de mi pantalla. Lo que sí funciona es el enlace proporcionado por ofekshilon.com (ver el comentario anterior) que usa los bytes 66, 67 y 68 y da las dimensiones en milímetros. En mi pantalla obtengo correctamente w=480mm y h=270mm.

    – tuen

    12 de diciembre de 2018 a las 9:42


avatar de usuario
Kosi2801

No es posible determinar el tamaño físico exacto de un dispositivo de video en Windows, ya que depende de muchas variables (p. ej., perfil de monitor activo, resolución horizontal/vertical, tamaño de píxel, etc.), algunas de las cuales no están bajo el control de la computadora.

Piense, por ejemplo, en los dispositivos proyectores, donde el tamaño físico depende de la distancia al área de proyección que no se puede determinar mediante programación, ya que el proyector de video se puede mover manualmente en cualquier momento.

  • +1, tendría que preguntarse de qué serviría saber el tamaño físico en lugar de la resolución real.

    – usuario7116

    23 de febrero de 2009 a las 14:27

  • /me cree que Kosi2801 acaba de declararse alemán al usar la palabra “beamer”. Realmente no significa “proyector de video” en inglés. 🙂

    – relajarse

    23 de febrero de 2009 a las 14:37

  • jeje, ahora sé la jerga alemana para proyector. ¡Agradable! Stackoverflow como un crisol técnico intercultural: increíble.

    – Adán Davis

    23 de febrero de 2009 a las 14:59

  • ¿Cómo podrían afectar exactamente la resolución horizontal/vertical y el tamaño de píxel a la físico tamaño de un monitor? He cambiado mucho la resolución y nunca he notado que mi monitor crece o se encoge. Cierto sobre los proyectores, pero eso no implica automáticamente que obtener el tamaño físico sea siempre imposible. Solo que es imposible para proyectores y similares.

    – jalf

    6 de septiembre de 2011 a las 8:35


  • En un monitor CRT, cambiar las resoluciones y el tamaño de píxel puede afectar la cantidad de tubo que se usa para mostrar la imagen, cambiando efectivamente el tamaño de la pantalla. Las imágenes CRT tienden a encogerse ligeramente con la edad del tubo, razón por la cual muchos esquemas de visualización sobreexploran.

    – Adrián McCarthy

    01/04/2018 a las 21:55

avatar de usuario
ofek shilon

La navegación directa por el registro no solo no es compatible, sino que también falla en dispositivos diferentes al suyo. (por ejemplo, en el que probé su código).

A diferencia de lo que algunos aquí dicen, hay es una forma oficial de acceder a la ruta de la clave EDID: mediante el uso de la API de configuración, y específicamente ConfiguraciónDiOpenDevRegKey.

Hay una configuración tediosa involucrada: El código de muestra está aquí.


EDITAR: se manejan múltiples monitores aquí.

  • Su código no funciona para múltiples monitores ya que GetsizeForDevID ignora el dispositivo usado, siempre recupera el tamaño del último. El tamaño del primero siempre se ignora.

    – Samuel

    20 de septiembre de 2013 a las 11:14

  • Advertencia: EDID no está disponible para todos los monitores.

    – Adrián McCarthy

    01/04/2018 a las 21:52

No puede obtener el tamaño exacto real: puede obtener una aproximación que depende de la configuración de DPI en Windows y la resolución de la pantalla, pero no puede garantizar que este sea el tamaño real.

Especialmente en una situación de varios monitores con diferentes pantallas (por ejemplo, un CRT de 19″ y un LCD de 24″). Además, si la pantalla es CRT, la medida es la medida del tubo y no el área de visualización.

Cuando los programas necesitaban esta información exactamente en el pasado, mostraban un indicador en la pantalla y hacían que el usuario sostuviera una hoja de papel en la pantalla y midiera el ancho del papel con el indicador. Dado que el papel es de 8.5 “o A4, entonces conoce el ancho y puede usar el número que ingresan para calcular el DPI real para una pantalla determinada. Es posible que necesite que lo hagan para cada monitor en una configuración de varios monitores.

-Adán

avatar de usuario
TipoDragón

Windows Vista y superior admiten la nueva función GetMonitorDisplayAreaSize()
http://msdn.microsoft.com/en-us/library/ms775210%28VS.85%29.aspx

Actualización: no funciona correctamente

avatar de usuario
pablo dixon

Puede solicitar LOGPIXELSX a ObtenerDeviceCaps para obtener el DPI de la pantalla, aunque generalmente devolverá 96. Consulte también esto Artículo de MSDN sobre cómo escribir aplicaciones compatibles con DPI.

avatar de usuario
Michael Myers

Puede obtener EDID del registro.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad