Monitor secondary coordinates are weird when using dpiawareness = 1

I have two monitors:

DISPLAY2: 3840x2160 (primary (no idea why it called DISPLAY2 though)
DISPLAY1: 1920x1080 (located right of primary)

      

I wrote a small program to print my geometry and it outputs:

\\.\DISPLAY2; x=0, y=0; 3840x2160
\\.\DISPLAY1; x=3840, y=278; 1920x1080

      

Which looks right. However, if I call SetProcessDpiAwareness((PROCESS_DPI_AWARENESS) 1);

, then it prints:

\\.\DISPLAY2; x=0, y=0; 7680x4320
\\.\DISPLAY1; x=7680, y=556; 3840x2160

      

Why did the dimensions just double?

Please note that I am not using any scaling factor on my monitors to understand what is going on in the first place. But this is what it prints if I set the scaling to 2x on the main monitor:

\\.\DISPLAY2; x=0, y=0; 3840x2160
\\.\DISPLAY1; x=7680, y=556; 3840x2160

      

Why does the secondary monitor start at x = 7680?

Here's the code I used to print the values:

#include <Windows.h>
#include <iostream>
#include <ShellScalingAPI.h>

#pragma comment(lib, "Shcore.lib")
#pragma comment(lib, "User32.lib")

BOOL monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM)
{
    MONITORINFOEX info;
    memset(&info, 0, sizeof(MONITORINFOEX));
    info.cbSize = sizeof(MONITORINFOEX);
    if (!GetMonitorInfo(hMonitor, &info))
        return false;

    std::cout << info.szDevice << "; x="<< info.rcMonitor.left << ", y=" << info.rcMonitor.top << "; "
              << (info.rcMonitor.right - info.rcMonitor.left) << "x" << (info.rcMonitor.bottom - info.rcMonitor.top)
              << "\n";

    return true;
}

int main()
{
    int result = SetProcessDpiAwareness((PROCESS_DPI_AWARENESS) 1);
    if (result) {
        std::cout << "Failed to call SetProcessDpiAwareness\n";
        return 1;
    }

    EnumDisplayMonitors(0, 0, monitorEnumCallback, reinterpret_cast<LPARAM>(&result));
    return 0;
}

      

+3


source to share


1 answer


It might be enlightening to (1) print out the system DPI for each case and (2) also try SetProcessDpiAwareness (PROCESS_PER_MONITOR_DPI_AWARE). The DPI for your two monitors is probably different (or at least Windows thinks they are).

You told Windows you know one system-wide DPI. To make sure the apps are correct in this case, Windows has come up with a virtual screen coordinate system that allows apps that base all their layouts on the DPI of the primary monitor to get good results on both monitors. If it was using the DPI of the primary monitor, your program might not select the best icon sizes and coordinates when drawing on the secondary monitor. Likewise, if it was using the DPI of the secondary monitor, apps would not be able to do pixel positioning on the primary. Using a double DPI increase and then scaling is probably a reasonable compromise if you look at all the interactions with the GDI (ClearType) GUI, Direct2D, mouse and pointer messages, etc.



If your application is designed to monitor DPI for each monitor, then I suspect you will get true values ​​across the board.

+3


source







All Articles