I need to get the real screen resolution, that is the resolution that actual output by the gpu, for each of the multiple screen, without affecting by dpi settings. I tried many answers from SO, but none of them seems to handle it correctly.
Some of the answers I tried:
- Is GetScaleFactorForMonitor winapi returning incorrect scaling factor? Calling
SetProcessDpiAwarenessContext()
orSetProcessApiAware()
does not help,GetScaleFactorForMonitor()
never returns the correct scale factor for anything other than 100% dpi.
-GetDpiForMonitor()
also does not return the correct dpi. And the dpiX
and dpiY
it returns does not even match.
Code:
static int result = []() {SetProcessDpiAwareness(PROCESS_DPI_UNAWARE); return 1; }(); //nope
struct MonitorInfo
{
MONITORINFO m_moniforInfo;
UINT dpiX{};
UINT dpiY{};
};
static std::vector<MonitorInfo> monitors;
BOOL EnumProc(HMONITOR monitor, HDC _, LPRECT __, LPARAM ___)
{
MONITORINFO monitorInfo{ sizeof(MONITORINFO) };
GetMonitorInfo(monitor, &monitorInfo);
UINT dpix;
UINT dpiy;
GetDpiForMonitor(monitor, MDT_RAW_DPI, &dpix, &dpiy);
monitors.push_back(MonitorInfo{ monitorInfo, dpix, dpiy});
return true;
}
int main()
{
SetProcessDpiAwareness(PROCESS_DPI_UNAWARE); //nope
EnumDisplayMonitors(nullptr, nullptr, EnumProc, 0);
for (auto const& monitor : monitors)
{
auto width = monitor.m_moniforInfo.rcMonitor.right - monitor.m_moniforInfo.rcMonitor.left;
auto height = monitor.m_moniforInfo.rcMonitor.bottom - monitor.m_moniforInfo.rcMonitor.top;
std::cout << width << " x " << height << '\t' << "dpix: " << monitor.dpiX << '\t' << monitor.dpiY << '\n';
}
}
Output, comments in (parens)
2560 x 1440 dpix: 108 109 (this is 3840*2160 with 150% scale)
2560 x 1440 dpix: 109 109 (this is 2560*2160 with 100% scale)
1920 x 1080 dpix: 163 106 (this is 3840*2160 with 200% scale)
1080 x 1920 dpix: 90 89 (this is 1080*1920 with 100% scale, shouldn't it be 96d?)
1920 x 1080 dpix: 163 106 (this is 3840*2160 with 200% scale too)