Подтвердить что ты не робот

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

Я хотел бы получить фактический экран dpi/ppi, а не параметр 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 точек на дюйм, что означает настройку для 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;
4b9b3361

Ответ 1

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

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

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

ОБНОВЛЕНО

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

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

Ответ 2

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

Microsoft имеет метод GetDpiForMonitor:

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

И мониторы DO раскрывают свои физические размеры инструментам. Вы можете читать ваши мониторы по ширине и высоте в сантиметрах с помощью инструмента 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 );

Ответ 4

Я думаю, что вам нужно:

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