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 !
Ants
March 28, 2010, March 28, 2010 08:54, permalink
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.
Enables a secondary monitor