Я хотел бы получить фактический экран 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;
То, что вы просите, к сожалению, невозможно в общем случае.
Windows не знает физического размера экрана. Windows может знать, что ваш экран имеет 1024×768 пикселей, но он не знает, насколько большой экран на самом деле. Вы можете вытащить кабель из старого 13-дюймового экрана и подключить его к 19-дюймовому монитору без изменения разрешения. DPI будет другим, но Windows не заметит, что вы сменили мониторы.
Вы можете получить истинные физические размеры и DPI для принтера (при условии, что драйвер не лежит), но не для экрана. По крайней мере, не надежно.
ОБНОВЛЕНО
Как уже отмечали другие, существуют стандарты двусторонней связи между новыми мониторами и ОС (EDID), которые могут сделать эту информацию доступной для некоторых устройств. Но я еще не нашел монитор, который предоставляет эту информацию.
Даже если бы EDID были доступны повсеместно, в общем случае это все равно невозможно решить, так как дисплей может быть видеопроектором, где DPI будет зависеть от масштаба, фокуса, типа объектива и расстояния проекции. Крайне маловероятно, что проектор будет знать расстояние проекции, поэтому у него нет возможности сообщить фактическое значение DPI.
Я честно смущен ответами здесь.
У Microsoft есть метод GetDpiForMonitor:
https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
И мониторы действительно выставляют свои физические размеры инструментам. Вы можете прочитать ширину и высоту ваших мониторов в сантиметрах, используя инструмент HWiNFO64. Так что, если они получают его (DDI?), Вполне понятно, что вы можете получить доступ к этой информации самостоятельно.
Даже в другой публикации о переполнении стека упоминается использование WmiMonitorBasicDisplayParams для получения данных.
Таким образом, верхний пост является плоским, 100%, неправильно.
Обнаружено, что получение информации DPI дает точное значение, используя метод ниже.
ID2D1Factory* m_pDirect2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
FLOAT dpiX, dpiY;
m_pDirect2dFactory->GetDesktopDpi( &dpiX, &dpiY );
Я думаю, что вы после того, как:
GetDeviceCaps(hdcScreen, LOGPIXELSX);
GetDeviceCaps(hdcScreen, LOGPIXELSY);