2010-01-04 38 views
5

Có thể lấy độ phân giải pixel màn hình bằng mm khi sử dụng API Win32 không? Tôi có một ứng dụng được hiển thị 0.3472222222222222 là giá trị cho điều này trên màn hình 1280x1024 của tôi với 96 dpi. Nhưng tôi không thể tìm ra cách nó có giá trị này. Mọi manh mối sẽ hữu ích. Tôi cũng có thể sử dụng MFC nếu cần.Độ phân giải pixel màn hình theo mm

EDIT Xin lỗi vì sự nhầm lẫn, phần mềm tôi đang nói đến không sử dụng độ phân giải màn hình hiện tại. Nó đã đọc nó từ một số tập tin cấu hình.

+0

25/72 = 0.347222. Không có ý tưởng nơi bạn có 25 từ. –

Trả lời

0

Sử dụng chức năng GetDC để xử lý trên màn hình, sau đó gọi hàm GetDeviceCaps để nhận kích thước màn hình tính bằng milimet. Ví dụ:

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

0.3472222222222222 mm trên mỗi pixel tương đương với khoảng 73 dpi. Windows sử dụng hai cài đặt chuẩn 72dpi và 96dpi, nhưng các giá trị tùy chỉnh cũng được hỗ trợ. Đây là những giá trị danh nghĩa và có thể không có bất kỳ mối quan hệ nào với màn hình vật lý. Ví dụ, có thể có màn hình 96dpi vật lý được đặt thành 72dpi và điều này sẽ ảnh hưởng đến việc chia tỷ lệ hình ảnh và bố cục trong các ứng dụng khác nhau cũng như kích thước phông chữ và biểu tượng hệ thống.

Giá trị mặc định cho Windows là 72dpi và tôi thấy rằng một số ứng dụng (thường là trong "Giới thiệu" và hộp thoại) không hiển thị chính xác khi được đặt thành các giá trị khác. Nếu ứng dụng của bạn báo cáo 0,34, có vẻ như nó được đặt thành 72dpi hoặc giá trị tùy chỉnh bất kể độ phân giải vật lý. Khi được đặt để phù hợp với độ phân giải vật lý, chiều rộng của trang trong Word nói ví dụ khi được đặt ở mức thu phóng 100% sẽ khớp với kích thước giấy vật lý. Vì chỉ số này có thể được thiết lập bởi người dùng cuối nên nó không liên quan trực tiếp đến độ phân giải thực tế.

8

mũ thiết bị Nhận cho màn hình mang đến cho bạn cả kích thước bằng pixel và mm như sau:

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

nhưng đó là những inch hợp lý phải không? – Ponting

+1

Có 25,4 mm mỗi inch - không 2,54. – Spire

+0

Cảm ơn bạn - chỉnh sửa chính xác – Elemental

2

Phần trên viết các ứng dụng "DPI-aware" trong MSDN là rất đáng đọc cho bất cứ ai quan tâm đến việc cung cấp phong nha hỗ trợ cho độ phân giải hiển thị biến. API để lấy thiết bị có liên quan & chỉ số hệ thống được mô tả here.

0

Đoạn mã dưới đây được chứng minh là cung cấp kết quả tốt nhất.

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

Tôi cũng đã có vấn đề tương tự như trên Windows 7 và cố gắng tiếp cận khác nhau nhưng không thể tìm thấy câu trả lời đúng cho đến khi tôi thấy điều này: http://ofekshilon.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/

Nó làm việc cho tôi cho các kích cỡ màn hình khác nhau!

#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; 
} 
Các vấn đề liên quan