How to obtain the correct physical size of the monitor?

后端 未结 7 1334
闹比i
闹比i 2020-12-01 10:13

How can I get the size of the display in centimeters or inches?

This code does not always works correctly:

HDC hdc = CreateDC(_T(\"DISPLAY\"),dd.Devi         


        
7条回答
  •  -上瘾入骨i
    2020-12-01 10:32

    I found another way. The physical size of the monitor are stored in the EDID, and Windows are almost always copies of its value in the registry. If you can parse EDID, you can read the width and height of the monitor in centimeters.

    Update: Added code

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

提交回复
热议问题