682a9ec8802319caf27eadd7666ae6e3

Enables a secondary monitor

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

Refactorings

No refactoring yet !

F9a9ba6663645458aa8630157ed5e71e

Ants

March 28, 2010, March 28, 2010 08:54, permalink

No rating. Login to rate!

For your P/Invoke declarations where you pass pointers, you may want to use UIntPtr rather than uint, so that you won't get frustrated wondering things stop working when you run on a 64-bit OS.

In EnableSecondaryDevice(), some of the hardcoded magic numbers almost make sense, but the 7 stands out as truly magic. Perhaps declare a const with a variable name the explains this.

Your refactoring





Format Copy from initial code

or Cancel