2010-01-04 5 views
5

E 'possibile ottenere la risoluzione pixel dello schermo in mm utilizzando le API Win32? Ho una domanda che sta mostrando ,3472222222222222 come valore per questo sul mio monitor 1280x1024 con 96 dpi. Ma non sono in grado di scoprire come ha ottenuto questo valore. Qualsiasi indizio sarà utile. Posso usare MFC anche se richiesto.schermo in mm

EDIT Scusate per la confusione, il software di cui sto parlando non utilizzava la risoluzione dello schermo corrente. Stava leggendolo da qualche file di configurazione.

+0

25/72 = 0,347222. Nessuna idea da dove hai preso 25 da. –

risposta

0

Utilizzare la funzione GetDC per ottenere una maniglia sul monitor, quindi chiamare la funzione GetDeviceCaps per ottenere la dimensione del monitor in millimetri. Ad esempio:

HDC monitor = GetDC(NULL); 
int horizSize = GetDeviceCaps(monitor, HORZSIZE); 
int vertSize = GetDeviceCaps(monitor, VERTSIZE); 
4

0,3472222222222222 mm per pixel è infatti pari a circa 73 dpi. Windows utilizza due impostazioni standard 72dpi e 96 dpi, ma sono supportati anche i valori personalizzati. Questi sono valori nominali e potrebbero non avere alcuna relazione con lo schermo fisico. Ad esempio, è possibile avere un set schermo fisicamente 96dpi a 72dpi, e questo influenzerà la scala delle immagini e la layout in varie applicazioni, così come la dimensione dei font di sistema e icone.

L'impostazione di default per Windows è 72dpi, e ho scoperto che alcune applicazioni (spesso nel loro "Chi" e finestre di dialogo) non rendano correttamente quando è impostata su altri valori. Se la tua applicazione riporta 0,34, sembra probabile che sia impostata su 72 dpi o un valore personalizzato indipendentemente dalla risoluzione fisica. Se impostato per corrispondere alla risoluzione fisica, la larghezza della pagina, ad esempio Word, ad esempio quando si imposta un livello di zoom del 100% corrisponderà alle dimensioni della carta fisica. Poiché questa metrica può essere impostata dall'utente finale, non è direttamente correlata alla risoluzione effettiva.

8

tappi dispositivo ottiene per il monitor che si dà sia dimensione in pixel e mm così:

HDC screen = GetDC(NULL); 
int hSize=GetDeviceCaps(screen,HORZSIZE); 
int hRes=GetDeviceCaps(screen,HORZRES); 
float PixelsPerMM=(float)hRes/hSize; // pixels per millimeter 
float PixelsPerInch=PixelsPerMM*25.4; //dpi 
+5

ma quelli sono pollici logici non è vero? – Ponting

+1

Ci sono 25,4 millimetri per pollice - non 2,54. – Spire

+0

Grazie - modificato per essere corretto – Elemental

2

La sezione sulla scrittura di applicazioni "DPI-aware" in MSDN merita una lettura per chiunque sia interessato a fornire decente supporto per risoluzioni di visualizzazione variabili. API per ottenere importanti metriche di sistema dispositivo & sono descritti here.

0

Il seguente codice frammento dimostrato di fornire il miglior risultato.

ID2D1Factory* m_pDirect2dFactory; 
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory); 
FLOAT dpiX, dpiY; 
m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY); 
1

Ho anche avuto problemi simili in Windows 7 e provare diversi approcci, ma non riusciva a trovare la risposta giusta fino a quando ho trovato questo: http://ofekshilon.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/

Funziona per me per le diverse dimensioni dello schermo!

#include <atlstr.h> 
#include <SetupApi.h> 
#pragma comment(lib, "setupapi.lib") 

#define NAME_SIZE 128 

const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}; 

// Assumes hDevRegKey is valid 
bool GetMonitorSizeFromEDID(const HKEY hDevRegKey, short& WidthMm, short& HeightMm) 
{ 
    DWORD dwType, AcutalValueNameLength = NAME_SIZE; 
    TCHAR valueName[NAME_SIZE]; 

    BYTE EDIDdata[1024]; 
    DWORD edidsize=sizeof(EDIDdata); 

    for (LONG i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; ++i) 
    { 
     retValue = RegEnumValue (hDevRegKey, i, &valueName[0], 
      &AcutalValueNameLength, NULL, &dwType, 
      EDIDdata, // buffer 
      &edidsize); // buffer size 

     if (retValue != ERROR_SUCCESS || 0 != _tcscmp(valueName,_T("EDID"))) 
      continue; 

     WidthMm = ((EDIDdata[68] & 0xF0) << 4) + EDIDdata[66]; 
     HeightMm = ((EDIDdata[68] & 0x0F) << 8) + EDIDdata[67]; 

     return true; // valid EDID found 
    } 

    return false; // EDID not found 
} 

bool GetSizeForDevID(const CString& TargetDevID, short& WidthMm, short& HeightMm) 
{ 
    HDEVINFO devInfo = SetupDiGetClassDevsEx(
     &GUID_CLASS_MONITOR, //class GUID 
     NULL, //enumerator 
     NULL, //HWND 
     DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| 
     NULL, // device info, create a new one. 
     NULL, // machine name, local machine 
     NULL);// reserved 

    if (NULL == devInfo) 
     return false; 

    bool bRes = false; 

    for (ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i) 
    { 
     SP_DEVINFO_DATA devInfoData; 
     memset(&devInfoData,0,sizeof(devInfoData)); 
     devInfoData.cbSize = sizeof(devInfoData); 

     if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData)) 
     { 
      HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData, 
       DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); 

      if(!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE)) 
       continue; 

      bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm); 

      RegCloseKey(hDevRegKey); 
     } 
    } 
    SetupDiDestroyDeviceInfoList(devInfo); 
    return bRes; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    short WidthMm, HeightMm; 

    DISPLAY_DEVICE dd; 
    dd.cb = sizeof(dd); 
    DWORD dev = 0; // device index 
    int id = 1; // monitor number, as used by Display Properties > Settings 

    CString DeviceID; 
    bool bFoundDevice = false; 
    while (EnumDisplayDevices(0, dev, &dd, 0) && !bFoundDevice) 
    { 
     DISPLAY_DEVICE ddMon; 
     ZeroMemory(&ddMon, sizeof(ddMon)); 
     ddMon.cb = sizeof(ddMon); 
     DWORD devMon = 0; 

     while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0) && !bFoundDevice) 
     { 
      if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE && 
       !(ddMon.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) 
      { 
       DeviceID.Format (L"%s", ddMon.DeviceID); 
       DeviceID = DeviceID.Mid (8, DeviceID.Find (L"\\", 9) - 8); 

       bFoundDevice = GetSizeForDevID(DeviceID, WidthMm, HeightMm); 
      } 
      devMon++; 

      ZeroMemory(&ddMon, sizeof(ddMon)); 
      ddMon.cb = sizeof(ddMon); 
     } 

     ZeroMemory(&dd, sizeof(dd)); 
     dd.cb = sizeof(dd); 
     dev++; 
    } 

    return 0; 
} 
Problemi correlati