Domanda

Come posso ottenere la dimensione del display in centimetri o pollici?

Questo codice non lo fa sempre funzioni correttamente:

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

In particolare per la configurazione multi-monitor.

Aggiornamento: Ho bisogno di ottenere la dimensione solo per i monitor normali, che hanno una dimensione fisica costante

.
È stato utile?

Soluzione

Ho trovato un altro modo. La dimensione fisica del monitor vengono memorizzati nel EDID, e Windows sono quasi sempre le copie del suo valore nel Registro di sistema. Se è possibile analizzare EDID, è possibile leggere la larghezza e l'altezza del monitor in centimetri.

Aggiornamento: il codice Aggiunto

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

Altri suggerimenti

Non è possibile determinare la dimensione esatta fisica di un dispositivo video su finestre poiché dipende un sacco di variabili (ad esempio profilo attivo monitor, risoluzione orizzontale / verticale, dimensione dei pixel, ecc), alcuni dei quali sono non sotto il controllo del computer.

Si pensi per esempio di dispositivi proiettore, in cui la dimensione fisica dipende dalla distanza di proiezione che non può essere determinato a livello di programmazione, come il videoproiettore può essere spostato manualmente in qualsiasi momento.

La navigazione nel Registro di sistema direttamente non solo è supportato, ma in realtà non riesce per i vari dispositivi della tua. (Per esempio, quello in cui ho provato il codice).

A differenza di quello che alcuni dicono qui, là è un modo ufficiale di accedere al percorso della chiave EDID: con l'uso del Setup API, e in particolare SetupDiOpenDevRegKey .

C'è un po 'di installazione noioso coinvolti - codice di esempio nofollow noreferrer è qui .


EDIT: più monitor sono gestite qui .

Non è possibile ottenere la vera dimensione esatta - si può ottenere un'approssimazione che dipende dalle impostazioni DPI in Windows, e la risoluzione dello schermo, ma non si può garantire che questa è la dimensione reale

Soprattutto in una situazione multimonitor con diversi display (diciamo un CRT e 24" 19" LCD). Inoltre, se il display è CRT, allora la misura è la misura del tubo, e non l'area di visualizzazione.

Quando i programmi hanno bisogno di queste informazioni esattamente in passato, hanno dimostrato una sullo schermo calibro, e aveva l'utente in possesso di un pezzo di carta fino allo schermo e misurare la larghezza della carta con il calibro. Data la carta è 8,5" o A4 poi si sa la larghezza, ed è possibile utilizzare il numero che di input per capire il vero DPI per un dato di visualizzazione. Potrebbe essere necessario averli farlo per ogni monitor in una configurazione multimonitor.

-Adam

Windows Vista e supporto superiore nuova funzione GetMonitorDisplayAreaSize () http://msdn.microsoft.com/en- us / library / ms775210% 28VS.85% 29.aspx

Update: Non funziona correttamente

È possibile richiedere LOGPIXELSX da GetDeviceCaps per ottenere il DPI per il display, anche se in genere tornare 96. Vedi anche questo articolo di MSDN sulla scrittura di applicazioni DPI-aware .

È possibile ottenere EDID dal Registro di sistema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top