c++windowsmultiple-monitorshighdpi

How to detect native screen resolution or scaling factor of the secondary monitor at Windows 10


Have two monitors: secondary to the left from primary. Resolutions:

Primary:   2560*1440 scaling 100%
Secondary: 1920*1200 scaling 150%

At the program start it does EnumDisplayMonitors which gives following RECTs:

Primary:   0,0,2560,1440
Secondary: -1920,0,-640,800

Also I tried the code:

int width, height;
RECT rect = { -1920, 0, -640, 800 };
SystemParametersInfoA(SPI_SETWORKAREA, 0, &rect, 0);
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);

but width and height always have dimensions of the primary monitor.

How to detect native resolution of the secondary monitor 1920*1200 or the scaling factor 150%?

This doesn't work either, gives 1280*800:

BOOL CALLBACK EnumMonitorCallback(HMONITOR hMon, HDC hdc, LPRECT rect, LPARAM param)
{
    MONITORINFOEXA mi;
    mi.cbSize = sizeof(mi);
    GetMonitorInfoA(hMon, &mi);
    HDC dc = CreateDCA("DISPLAY", mi.szDevice, NULL, NULL);
    int width = GetDeviceCaps(dc, HORZRES);
    int height = GetDeviceCaps(dc, VERTRES);
    DeleteDC(dc);
    return TRUE;
}

Solution

  • Your application should indicate High DPI awareness so that OS does not try to lie about resolutions trying to mimic legacy environment. Then DXGI output enumeration gets you the requested data.

    You can quick-check this using tool at the bottom of this blog post. I have two monitors at 3840x2160, the first with 175% scaling and the second with 150%. Note "desktop coordinates" and "monitor DPI" in the printout below:

    #### Output: \\.\DISPLAY4
    
     * Desktop Coordinates: (0, 0) - (3840, 2160); 3840 x 2160
     * Attached To Desktop: 1
     * Rotation: DXGI_MODE_ROTATION_IDENTITY
     * Monitor: 0x000100B3
     * Physical Monitors: LG ULTRA HD(DisplayPort) (0x00000000)
     * Bits Per Color: 10
     * Color Space: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
     * Primaries, White Point: R { 0.652, 0.335 }, G { 0.305, 0.637 }, B { 0.148, 0.062 }; { 0.313, 0.329 }
     * Luminance: Min 0.500, Max 270.000, Max Full Frame 270.000
     * Hardware Composition Support: DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_FULLSCREEN | DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHED
     * Monitor DPI, MDT_EFFECTIVE_DPI: 168, 168 ; System DPI 168
     * Monitor DPI, MDT_ANGULAR_DPI: 161, 160
     * Monitor DPI, MDT_RAW_DPI: 162, 161
    
    …
    
    #### Output: \\.\DISPLAY5
    
     * Desktop Coordinates: (3840, 0) - (7680, 2160); 3840 x 2160
     * Attached To Desktop: 1
     * Rotation: DXGI_MODE_ROTATION_IDENTITY
     * Monitor: 0x000200B1
     * Physical Monitors: LG ULTRA HD(DisplayPort) (0x00000000)
     * Bits Per Color: 10
     * Color Space: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
     * Primaries, White Point: R { 0.652, 0.335 }, G { 0.305, 0.637 }, B { 0.148, 0.062 }; { 0.313, 0.329 }
     * Luminance: Min 0.500, Max 270.000, Max Full Frame 270.000
     * Hardware Composition Support: DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_FULLSCREEN | DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHED
     * Monitor DPI, MDT_EFFECTIVE_DPI: 144, 144 ; System DPI 168
     * Monitor DPI, MDT_ANGULAR_DPI: 161, 160
     * Monitor DPI, MDT_RAW_DPI: 162, 161