Получение фактического экрана dpi / ppi под окнами

Я хотел бы получить фактический экран dpi / ppi, а не параметр dpi, используемый для шрифта в C ++.

Я пробовал со следующими кодами:

Версия 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 точек на дюйм, который является настройкой шрифта в Windows для шрифта, но не фактическое разрешение экрана.

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

19

Решение

То, что вы просите, к сожалению, невозможно в общем случае.

Windows не знает физического размера экрана. Windows может знать, что ваш экран имеет 1024×768 пикселей, но он не знает, насколько большой экран на самом деле. Вы можете вытащить кабель из старого 13-дюймового экрана и подключить его к 19-дюймовому монитору без изменения разрешения. DPI будет другим, но Windows не заметит, что вы сменили мониторы.

Вы можете получить истинные физические размеры и DPI для принтера (при условии, что драйвер не лежит), но не для экрана. По крайней мере, не надежно.

ОБНОВЛЕНО

Как уже отмечали другие, существуют стандарты двусторонней связи между новыми мониторами и ОС (EDID), которые могут сделать эту информацию доступной для некоторых устройств. Но я еще не нашел монитор, который предоставляет эту информацию.

Даже если бы EDID были доступны повсеместно, в общем случае это все равно невозможно решить, так как дисплей может быть видеопроектором, где DPI будет зависеть от масштаба, фокуса, типа объектива и расстояния проекции. Крайне маловероятно, что проектор будет знать расстояние проекции, поэтому у него нет возможности сообщить фактическое значение DPI.

13

Другие решения

Я честно смущен ответами здесь.

У Microsoft есть метод GetDpiForMonitor:

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

И мониторы действительно выставляют свои физические размеры инструментам. Вы можете прочитать ширину и высоту ваших мониторов в сантиметрах, используя инструмент HWiNFO64. Так что, если они получают его (DDI?), Вполне понятно, что вы можете получить доступ к этой информации самостоятельно.

Даже в другой публикации о переполнении стека упоминается использование WmiMonitorBasicDisplayParams для получения данных.

Как получить размер монитора

Таким образом, верхний пост является плоским, 100%, неправильно.

3

Обнаружено, что получение информации DPI дает точное значение, используя метод ниже.

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

Я думаю, что вы после того, как:

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

1
По вопросам рекламы [email protected]