Pregunta

¿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 multi-monitor.

Actualización: que necesito para obtener el tamaño justo para los monitores ordinarios, que tienen un tamaño físico constante

.
¿Fue útil?

Solución

He encontrado otra manera. El tamaño físico de la pantalla se almacenan en el EDID y Windows son casi siempre copias de su valor en el registro. Si se puede analizar EDID, se puede leer la anchura y la altura del monitor en centímetros.

Actualización: código Añadido

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;
}

Otros consejos

No es posible determinar el tamaño físico exacto de un dispositivo de vídeo en las ventanas ya que esto depende mucho de las variables (por ejemplo, el perfil activo del monitor, la resolución horizontal / vertical, tamaño de píxel, etc.), algunos de los cuales son no están bajo el control del ordenador.

Piense por ejemplo de dispositivos de proyección, donde el tamaño físico depende de la distancia a la zona de proyección que no se puede determinar mediante programación, como el proyector de vídeo podría ser movido manualmente en cualquier momento.

Navegando por el registro es directamente no sólo no compatible, pero en realidad no para dispositivos diferentes a la suya. (Por ejemplo, aquella en la que he probado su código).

A diferencia de lo que algunos dicen aquí, hay es una forma oficial de acceso a la ruta de la clave EDID: mediante el uso de la API de instalación, y en concreto SetupDiOpenDevRegKey .

Hay un poco tediosa configuración involucrados - código de forma / de la muestra es aquí .


EDIT: varios monitores se manejan aquí .

No se puede obtener el tamaño exacto de bienes - se puede obtener una aproximación que depende de la configuración de PPP en las ventanas, y la resolución de la pantalla, pero no se puede garantizar que este es el tamaño real

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

Cuando los programas han necesitado esta información exactamente en el pasado, que han mostrado un medidor en pantalla, y tenía el usuario mantenga un trozo de papel hasta la pantalla y medir la anchura del papel con el medidor. Dado el papel es de 8,5" o A4 entonces usted sabe el ancho, y se puede usar el número que de entrada para averiguar el valor real de PPP para una pantalla dada. Es posible que necesite tener a hacer eso para cada monitor en una configuración de varios monitores.

-Adán

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

Actualización: No funciona correctamente

Puede solicitar LOGPIXELSX de GetDeviceCaps para obtener el DPI para la pantalla, a pesar de que generalmente volverá 96. Véase también esta artículo de MSDN sobre cómo escribir aplicaciones DPI-conscientes .

Puede obtener EDID del registro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top