23

我想获得实际的屏幕 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

4 回答 4

14

不幸的是,您所要求的在一般情况下是不可能的。

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

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

更新

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

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

于 2012-09-29T16:36:56.880 回答
14

老实说,我对这里的答案感到困惑。

微软有一个 GetDpiForMonitor 方法:

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

监视器确实将其物理尺寸暴露给工具。您可以使用 HWiNFO64 工具读取显示器的宽度和高度(以厘米为单位)。因此,如果他们得到它(DDI?),那么您可以自己访问该信息是有道理的。

甚至另一个 Stack Overflow 帖子也提到使用 WmiMonitorBasicDisplayParams 来获取数据。

如何获得显示器尺寸

所以上面的帖子是完全错误的,100%是错误的。

于 2017-02-02T06:08:30.963 回答
1

发现使用以下方法获取 DPI 信息可以产生准确的值。

ID2D1Factory* m_pDirect2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
FLOAT dpiX, dpiY;
m_pDirect2dFactory->GetDesktopDpi( &dpiX, &dpiY );
于 2012-12-19T11:33:02.673 回答
0

我想你追求的是:

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

于 2016-05-02T17:15:04.267 回答