2010-01-04 87 views
5

使用Win32 API可以以mm爲單位獲得屏幕像素分辨率嗎?我有一個應用程序,它顯示0.3472222222222222作爲此值在我的1280x1024顯示器與96 dpi。但我無法瞭解它是如何得到這個價值的。任何線索都會有所幫助。如果需要,我也可以使用MFC。以mm爲單位的屏幕像素分辨率

編輯 對不起,我說的軟件沒有使用當前的屏幕分辨率。它從一些配置文件中讀取它。

+0

25/72 = 0.347222。不知道你從哪裏得到25。 – 2010-01-05 22:08:32

回答

0

使用GetDC函數來獲取顯示器上的句柄,然後調用GetDeviceCaps函數以毫米爲單位獲取顯示器的大小。例如:

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

0.3472222222222222毫米每像素實際上相當於大約73 dpi。 Windows使用兩個標準設置72dpi和96dpi,但也支持自定義值。這些是名義值,可能與物理屏幕沒有任何關係。例如,可以將96dpi的物理屏幕設置爲72dpi,這會影響各種應用程序中圖像和佈局的縮放比例以及系統字體和圖標的大小。

Windows的默認值是72dpi,我發現某些應用程序(通常在其「關於」和對話框中)在設置爲其他值時無法正確呈現。如果您的應用程序報告0.34,則無論物理分辨率如何,它似乎可能設置爲72dpi或自定義值。當設置爲與物理分辨率匹配時,例如當設置爲100%的縮放級別時,例如Word中的頁面寬度將與物理紙張大小相匹配。由於此度量標準可由最終用戶設置,因此與實際分辨率無直接關係。

8

的顯示器獲得設備帽讓你在像素和毫米兩種尺寸這樣的:

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

但這些都是邏輯英寸是不是? – Ponting 2010-01-04 17:08:01

+1

每英寸有25.4毫米 - 而不是2.54毫米。 – Spire 2010-02-12 04:50:38

+0

謝謝 - 編輯正確 – Elemental 2010-02-16 08:18:25

2

的部分上寫入MSDN「DPI感知」的應用程序是非常值得一讀有興趣的人提供體面支持可變顯示分辨率。描述用於獲得相關設備&系統度量的API here

0

下面的代碼片段證明可以提供最好的結果。

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

我也有過類似的問題上Windows 7的,並嘗試不同的方法,但無法找到正確的答案,直到我發現這一點:http://ofekshilon.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/

這對我的作品不同的屏幕大小!

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