2010-01-04 4 views
5

Est-il possible d'obtenir la résolution en pixels de l'écran en mm à l'aide des API Win32? J'ai une application qui montre 0.3472222222222222 comme la valeur pour ceci sur mon moniteur 1280x1024 avec 96 dpi. Mais je ne suis pas capable de savoir comment cela a eu cette valeur. Des indices seront utiles. Je peux utiliser MFC aussi si nécessaire.Résolution des pixels de l'écran en mm

EDIT Désolé pour la confusion, le logiciel dont je parle n'utilisait pas la résolution d'écran actuelle. Il était en train de le lire à partir d'un fichier de configuration.

+0

25/72 = 0,347222. Aucune idée d'où vous avez 25 ans. –

Répondre

0

Utilisez la fonction GetDC pour obtenir une poignée sur le moniteur, puis appelez la fonction GetDeviceCaps pour obtenir la taille du moniteur en millimètres. Par exemple:

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

0,3472222222222222 mm par pixel est en fait équivalent à environ 73 dpi. Windows utilise deux paramètres standard 72dpi et 96dpi, mais les valeurs personnalisées sont également prises en charge. Ce sont des valeurs nominales et peuvent ne pas avoir de relation avec l'écran physique. Par exemple, il est possible d'avoir un écran physique de 96dpi à 72dpi, ce qui affectera la mise à l'échelle des images et de la disposition dans diverses applications ainsi que la taille des polices et des icônes du système. La valeur par défaut pour Windows est 72dpi, et j'ai constaté que certaines applications (souvent dans leur "À propos de" et boîtes de dialogue) ne rendent pas correctement lorsqu'ils sont mis à d'autres valeurs. Si votre application indique 0.34, il semble probable qu'elle est définie sur 72 dpi ou sur une valeur personnalisée quelle que soit la résolution physique. Lorsqu'elle est définie pour correspondre à la résolution physique, la largeur de la page dans Word, par exemple, lorsqu'elle est définie sur un niveau de zoom de 100%, correspond au format physique du papier. Étant donné que cette métrique peut être définie par l'utilisateur final, elle n'est pas directement liée à la résolution réelle.

8

bouchons des dispositifs Get pour le moniteur vous donne à la fois la taille en pixels et mm ainsi:

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

mais ce sont des pouces logiques n'est-ce pas? – Ponting

+1

Il y a 25,4 millimètres par pouce - pas 2,54. – Spire

+0

Merci - édité pour être correct – Elemental

2

La section sur l'écriture d'applications « DPI-courant » dans MSDN vaut bien une lecture pour toute personne intéressée à fournir décent support pour les résolutions d'affichage variables. Les API permettant d'obtenir les mesures système & pertinentes du périphérique sont décrites here.

0

L'extrait de code ci-dessous s'est avéré fournir le meilleur résultat.

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

J'ai aussi eu des problèmes similaires sur Windows 7 et essayer différentes approches, mais n'a pas pu trouver la bonne réponse jusqu'à ce que je trouve ceci: http://ofekshilon.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/

Il fonctionne pour moi pour différentes tailles d'écran!

#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; 
} 
Questions connexes