使用Win32 API可以获得mm的屏幕像素分辨率吗?我有一个应用程序显示0.34722222222222222作为我的1280x1024显示器上96dpi的值。但我无法弄清楚它是如何获得这个价值的。任何线索都会有所帮助。如果需要,我也可以使用MFC。
修改 对不起,我所说的软件没有使用当前的屏幕分辨率。它是从一些配置文件中读取的。
答案 0 :(得分:8)
获取显示器的设备上限为您提供像素和mm的尺寸:
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
答案 1 :(得分:4)
Windows的默认值为72dpi,我发现某些应用程序(通常在“关于”和对话框中)在设置为其他值时无法正确呈现。如果您的应用程序报告0.34,则无论物理分辨率如何,它都可能设置为72dpi或自定义值。设置为与物理分辨率匹配时,例如设置为100%缩放级别时的页面宽度将与实际纸张大小相匹配。由于此指标可由最终用户设置,因此与实际分辨率无直接关系。
答案 2 :(得分:2)
答案 3 :(得分: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;
}
答案 4 :(得分:0)
使用GetDC功能获取显示器上的句柄,然后调用GetDeviceCaps功能以毫米为单位获取显示器的大小。例如:
HDC monitor = GetDC( NULL );
int horizSize = GetDeviceCaps( monitor, HORZSIZE );
int vertSize = GetDeviceCaps( monitor, VERTSIZE );
答案 5 :(得分:0)
以下代码段证明可以提供最佳效果。
ID2D1Factory* m_pDirect2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
FLOAT dpiX, dpiY;
m_pDirect2dFactory->GetDesktopDpi( &dpiX, &dpiY );