5

I believe I will need an example of doing this in SetDisplayConfig().

My Windows-7 system has two monitors. When my program is in one mode, the 1st monitor must be on and primary, and the 2nd monitor off. In the other mode, vice versa: 1st monitor off, 2nd monitor on and primary.

I've searched and searched for how to do it with Windows SDK function "SetDisplayConfig()" but found nothing. The MSDN reference to SetDisplayConfig() is too esoteric for me, and has no example code.

I got it going using ChangeDisplaySettingsEx(), but this function is flaky in Windows-7.

Thanks!

Doug Null
  • 7,989
  • 15
  • 69
  • 148
  • See my answer in the duplicate question : http://stackoverflow.com/questions/16342757/how-can-i-temporarily-blank-a-windows-7-2nd-display-monitor-in-c – Xaruth May 06 '13 at 11:35

2 Answers2

7

I currently fiddle with both SetDisplayConfig() and ChangeDisplaySettingsEx() as well and found that this seems to work with my setup. SDC_TOPOLOGY_INTERNAL and SDC_TOPOLOGY_EXTERNAL refer to whatever Windows decides your primary (screen) and secondary (projector) monitor is, similar to the monitor selection when your press Win+P. It's the other way around for me, so you'd have to check whats the correct one in your configuration is. Then you can simply call InternalDisplay() or ExternalDisplay() to activate the one and automatically deactivate the other. I added the clone and extend settings for the sake of completeness.

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern long SetDisplayConfig(uint numPathArrayElements,
IntPtr pathArray, uint numModeArrayElements, IntPtr modeArray, uint flags);

UInt32 SDC_TOPOLOGY_INTERNAL = 0x00000001;
UInt32 SDC_TOPOLOGY_CLONE = 0x00000002;
UInt32 SDC_TOPOLOGY_EXTEND = 0x00000004;
UInt32 SDC_TOPOLOGY_EXTERNAL = 0x00000008;
UInt32 SDC_APPLY = 0x00000080;

public void CloneDisplays() {
  SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_CLONE));
}

public void ExtendDisplays() {
  SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_EXTEND));
 }

public void ExternalDisplay() {
  SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_EXTERNAL));
}

public void InternalDisplay() {
  SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_INTERNAL));
}
Lennart
  • 9,657
  • 16
  • 68
  • 84
0

The function SetDisplayConfig considers a monitor with topleft corner at (0, 0) as a primary monitor (all other monitors should be positioned relative to it). Such an info about coordinated of monitors should be provided to SetDisplayConfig with modeInfoArray parameter.

ribo8
  • 1