简体   繁体   中英

C# query windows screen underlying resolution without dpi multiplier

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.

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM