Как получить корректный физический размер монитора?

Похоже, ваша IDE указывает на JRE. Добавьте путь JDK в вашу среду IDE

Для Eclipse попробуйте выполнить следующие действия:

Windows -> perfernces -> java -> установленные JRE.

Добавьте свой JDK и нажмите на недавно добавленный JDK

для справки

.

10
задан KindDragon 4 October 2013 в 17:25
поделиться

5 ответов

Я нашел иначе. Физический размер монитора хранится в EDID, и Windows является почти всегда копиями своего значения в реестре. Если можно проанализировать EDID, можно считать ширину и высоту монитора в сантиметрах.

Обновление: Добавленный код

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;
}
18
ответ дан 3 December 2019 в 13:44
поделиться

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

Думайте, например, об устройствах проектора, где физический размер зависит от расстояния до области проекции, которая не может быть определена программно, поскольку видеопроектор мог быть перемещен вручную в любое время.

8
ответ дан 3 December 2019 в 13:44
поделиться

Вы не можете получить реальный точный размер - можно получить приближение, которое зависит от установки DPI в окнах и разрешения экрана, но Вы не можете гарантировать, что это - реальный размер.

Особенно в ситуации с мультимонитором с различными дисплеями (говорят что 19-дюймовый CRT и 24-дюймовый жидкокристаллический дисплей). Далее, если дисплеем является CRT затем, измерение является измерением трубы а не областью дисплея.

Когда для программ была нужна эта информация точно в прошлом, они показали индикатор на экране и сделали, чтобы пользователь держал листок бумаги до экрана и измерил бумажную ширину с индикатором. Учитывая бумагу 8,5 дюймов или A4 затем, Вы знаете ширину, и можно использовать число, которое они вводят для выяснения реального DPI для данного дисплея. Вы, возможно, должны сделать, чтобы они сделали это для каждого монитора в установке мультимонитора.

- Adam

5
ответ дан 3 December 2019 в 13:44
поделиться

Можно запросить LOGPIXELSX от GetDeviceCaps получить DPI для дисплея, хотя он будет обычно возвращаться 96. См. также эту статью MSDN о записи осведомленных о DPI приложений.

1
ответ дан 3 December 2019 в 13:44
поделиться

Windows Vista и более поздние версии поддерживают новую функцию GetMonitorDisplayAreaSize () http://msdn.microsoft.com/en-us/ library / ms775210% 28VS.85% 29.aspx

Обновление: не работает должным образом

4
ответ дан 3 December 2019 в 13:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: