0

Wrote an app that adjusts your background across multiple monitors depending on where they sit.

Works great if all the monitors are set to the same dpi settings - but in some cases I have a laptop where the screens are set to 100% - but the laptop is set to 250% in windows.

Screen.Allscreens is giving back the scaled resolution - but when I set the background - that's working in the underlying, "real" resolution - the net effect being I get 2.5 copies of my background image on the screen.

So - from C# - how do I query the actual screen resolution, not the scaled... or alternatively, the scaling factor. I found some pages that show me how to get the scaling factor, but you need a dc - and I can't figure out how to get that from each of the screens.

Darren Oakey
  • 2,894
  • 3
  • 29
  • 55
  • [Using SetWindowPos with multiple monitors](https://stackoverflow.com/a/53026765/7444103) -- What matters most is the application's DpiAwareness. Possibly setting `PerMonitorV2` . Some other information may be also useful. – Jimi May 13 '21 at 17:42

1 Answers1

0

Found an answer here:

C# - How to get real screen resolution in multiple monitors context?

Which led to this class:

public class Monitor
{
    private readonly Screen _screen;
    private readonly DEVMODE _device;

    private Monitor(Screen screen, DEVMODE device)
    {
        _screen = screen;
        _device = device;
    }

    const int ENUM_CURRENT_SETTINGS = -1;


    public Rectangle PhysicalBounds =>
        new(_device.dmPositionX, _device.dmPositionY, _device.dmPelsWidth,
            _device.dmPelsHeight);

    public Rectangle Bounds => _screen.Bounds;

    public string Name => _screen.DeviceName;

    public static Monitor[] All
    {
     get{
        return Screen.AllScreens.Select(Monitor.From).ToArray();
       }

    }

    private static Monitor From(Screen screen)
    {
        var dm = new DEVMODE {dmSize = (short) Marshal.SizeOf(typeof(DEVMODE))};
        EnumDisplaySettings(screen.DeviceName, ENUM_CURRENT_SETTINGS, ref dm);

        return new Monitor(screen, dm);


    }
    
    
    [DllImport("user32.dll")]
    public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);

    [StructLayout(LayoutKind.Sequential)]
    public struct DEVMODE
    {
        private const int CCHDEVICENAME = 0x20;
        private const int CCHFORMNAME = 0x20;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmDeviceName;
        public short dmSpecVersion;
        public short dmDriverVersion;
        public short dmSize;
        public short dmDriverExtra;
        public int dmFields;
        public int dmPositionX;
        public int dmPositionY;
        public ScreenOrientation dmDisplayOrientation;
        public int dmDisplayFixedOutput;
        public short dmColor;
        public short dmDuplex;
        public short dmYResolution;
        public short dmTTOption;
        public short dmCollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmFormName;
        public short dmLogPixels;
        public int dmBitsPerPel;
        public int dmPelsWidth;
        public int dmPelsHeight;
        public int dmDisplayFlags;
        public int dmDisplayFrequency;
        public int dmICMMethod;
        public int dmICMIntent;
        public int dmMediaType;
        public int dmDitherType;
        public int dmReserved1;
        public int dmReserved2;
        public int dmPanningWidth;
        public int dmPanningHeight;
    }
}
Darren Oakey
  • 2,894
  • 3
  • 29
  • 55