4
votes

I am writing a windows program which let user switch the resolution between 1920*1080 and 3840*2160, that means between FHD and 4K.

I tried to use "GetSystemMetrics" to get current resolution.

//Algorithm #1
//Get current resolution and resolution scaling.
xScreenResolution = GetSystemMetrics(SM_CXSCREEN);
yScreenResolution = GetSystemMetrics(SM_CYSCREEN);
cout << "Current Resolution is: " << xScreenResolution << "x" << yScreenResolution << endl;

For example, if I am using a resolution of 3840*2160, I expected the program will give me the resolution of 3840*2160. However, the program just outputs 1536x864, which is the resolution after Windows had performed rescaling.

So I want to know how to get the scaling factor (100%, 200%, 250%, etc.) programmatically like display settings in Windows 10. display settings in Windows 10

1

1 Answers

1
votes

It looks like your application receives virtualized DPI data. To receive correct metrics you need to provide a proper application manifest, including high DPI support and system compatibility entries. See High DPI.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
        </windowsSettings>
    </application>
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows 10 -->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
        </application>
    </compatibility>
</assembly>

To get scaling you can call GetDpiForMonitor.