“Extend my Windows desktop onto this monitor” programmatically

后端 未结 8 1110
不思量自难忘°
不思量自难忘° 2020-12-24 03:02

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 knowle

8条回答
  •  忘掉有多难
    2020-12-24 03:16

    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
        {
            /// The device is part of the desktop.
            AttachedToDesktop = 0x1,
            MultiDriver = 0x2,
            /// The device is part of the desktop.
            PrimaryDevice = 0x4,
            /// Represents a pseudo device used to mirror application drawing for remoting or other purposes.
            MirroringDriver = 0x8,
            /// The device is VGA compatible.
            VGACompatible = 0x16,
            /// The device is removable; it cannot be the primary display.
            Removable = 0x20,
            /// The device has more display modes than its output devices support.
            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.

提交回复
热议问题