Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Extend my Windows desktop onto this monitor" programmatically

Tags:

I would like to be able to set "Extend my Windows desktop onto this monitor" via code. A PowerShell script would be ideal. WMI seems the way forward but I have zero knowledge in WMI.

like image 546
Zi Makki Avatar asked Nov 08 '08 19:11

Zi Makki


People also ask

What does extend desktop to display mean?

Extended Desktop Definition The Extended Desktop mode means that all your monitors behave as one big screen. Each monitor displays a different section of the general display image. In other words, each monitor displays different things.

What is extend monitor?

Extending monitors means that your computer interprets the monitors that you are extending as separate devices. You can see different things on each monitor, and your desktop background is displayed on each monitor. In general, video splitters can only be used to mirror monitors.


2 Answers

Windows 7, 8 and 10 are supposed to come with a small program that does exactly this: displayswitch.exe. This page lists the following parameters:

displayswitch.exe /internal Disconnect projector (same as "Show only on 1" from the Display Properties dialog) displayswitch.exe /clone        Duplicate screen displayswitch.exe /extend    Extend screen displayswitch.exe /external Projector only (disconnect local) (same as "Show only on 2" from the Display Properties dialog) 

For a one-click solution to the problem posed, simply create a *.bat-file containing the single line

call displayswitch.exe /extend 

and save it to your desktop.

[I tested this on Windows 8.1, and it has been confirmed to work on Windows 10.]

like image 159
Communicative Algebra Avatar answered Oct 01 '22 15:10

Communicative Algebra


I've made a cleaner version that does not use sendkeys.

public class DisplayHelper
{
    [DllImport("user32.dll")]
    static extern DISP_CHANGE ChangeDisplaySettings(uint lpDevMode, uint dwflags);
    [DllImport("user32.dll")]
    static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

    enum DISP_CHANGE : int
    {
        Successful = 0,
        Restart = 1,
        Failed = -1,
        BadMode = -2,
        NotUpdated = -3,
        BadFlags = -4,
        BadParam = -5,
        BadDualView = -1
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    struct DISPLAY_DEVICE
    {
        [MarshalAs(UnmanagedType.U4)]
        public int cb;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string DeviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceString;
        [MarshalAs(UnmanagedType.U4)]
        public DisplayDeviceStateFlags StateFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceKey;
    }

    [Flags()]
    enum DisplayDeviceStateFlags : int
    {
        /// <summary>The device is part of the desktop.</summary>
        AttachedToDesktop = 0x1,
        MultiDriver = 0x2,
        /// <summary>The device is part of the desktop.</summary>
        PrimaryDevice = 0x4,
        /// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
        MirroringDriver = 0x8,
        /// <summary>The device is VGA compatible.</summary>
        VGACompatible = 0x16,
        /// <summary>The device is removable; it cannot be the primary display.</summary>
        Removable = 0x20,
        /// <summary>The device has more display modes than its output devices support.</summary>
        ModesPruned = 0x8000000,
        Remote = 0x4000000,
        Disconnect = 0x2000000
    }

    public static void EnableSecondaryDisplay()
    {
        var secondaryIndex = 1;
        var secondary = GetDisplayDevice(secondaryIndex);
        var id = secondary.DeviceKey.Split('\\')[7];

        using (var key = Registry.CurrentConfig.OpenSubKey(string.Format(@"System\CurrentControlSet\Control\VIDEO\{0}", id), true))
        {
            using (var subkey = key.CreateSubKey("000" + secondaryIndex))
            {
                subkey.SetValue("Attach.ToDesktop", 1, RegistryValueKind.DWord);
                subkey.SetValue("Attach.RelativeX", 1024, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.XResolution", 1024, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.YResolution", 768, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.BitsPerPel", 32, RegistryValueKind.DWord);
            }
        }

        ChangeDisplaySettings(0, 0);
    }

    private static DISPLAY_DEVICE GetDisplayDevice(int id)
    {
        var d = new DISPLAY_DEVICE();
        d.cb = Marshal.SizeOf(d);
        if (!EnumDisplayDevices(null, (uint)id, ref d, 0))
            throw new NotSupportedException("Could not find a monitor with id " + id);
        return d;
    }
}

I have only tested this on a newly installed computer.

like image 38
loraderon Avatar answered Oct 01 '22 15:10

loraderon