在Windows下获取实际屏幕dpi / ppi

时间:2012-09-29 12:50:32

标签: c++ windows screen dpi ppi

我想获得实际屏幕dpi / ppi,而不是C ++中用于字体的dpi设置。

我尝试使用以下代码:

版本1,报告72 dpi,这是错误的。

SetProcessDPIAware(); //true
HDC screen = GetDC(NULL);
double hSize = GetDeviceCaps(screen, HORZSIZE);
double vSize = GetDeviceCaps(screen, VERTSIZE);
double hRes = GetDeviceCaps(screen, HORZRES);
double vRes = GetDeviceCaps(screen, VERTRES);
double hPixelsPerInch = hRes / hSize * 25.4;
double vPixelsPerInch = vRes / vSize * 25.4;
ReleaseDC(NULL, screen);
return (hPixelsPerInch + vPixelsPerInch) * 0.5;

版本2,报告96 dpi,这是字体的Windows dpi设置,但不是实际的屏幕dpi。

SetProcessDPIAware(); //true
HDC screen = GetDC(NULL);
double hPixelsPerInch = GetDeviceCaps(screen,LOGPIXELSX);
double vPixelsPerInch = GetDeviceCaps(screen,LOGPIXELSY);
ReleaseDC(NULL, screen);
return (hPixelsPerInch + vPixelsPerInch) * 0.5;

4 个答案:

答案 0 :(得分:13)

遗憾的是,在一般情况下,你所要求的是不可能的。

Windows不知道物理屏幕大小。 Windows可能知道您的屏幕有1024x768像素,但它不知道屏幕实际有多大。您可以将电缆拉出旧的13英寸屏幕并将其连接到19英寸显示器而不更改分辨率。 DPI会有所不同,但Windows不会注意到您更改了监视器。

您可以获得打印机的真实物理尺寸和DPI(假设驱动程序没有说谎),但不能用于屏幕。至少不可靠。

<强>已更新

正如其他人所指出的那样,新的监视器和操作系统(EDID)之间存在双向通信的标准,可能会使这些信息可用于某些设备。但我还没有找到提供此信息的显示器。

即使EDID是普遍可用的,在一般情况下仍然无法解决,因为显示器可能是视频投影仪,其中DPI将取决于变焦,焦距,镜头类型和投射距离。投影机极不可能知道投射距离,因此无法报告实际的DPI。

答案 1 :(得分:4)

我真诚地对这里的答案感到困惑。

Microsoft有一个GetDpiForMonitor方法:

https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx

显示器DO将其物理尺寸暴露给工具。您可以使用HWiNFO64工具以厘米为单位读取显示器的宽度和高度。所以如果他们得到它(DDI?),你可以自己访问这些信息。

即使是不同的Stack Overflow帖子也提到使用WmiMonitorBasicDisplayParams来获取数据。

How to get monitor size

所以最高职位是100%,错误。

答案 2 :(得分:1)

使用以下方法可以获得DPI信息以产生精确值。

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

答案 3 :(得分:1)

我认为你所追求的是:

GetDeviceCaps(hdcScreen, LOGPIXELSX); GetDeviceCaps(hdcScreen, LOGPIXELSY);