# Change 2nd Monitor Display Setting to Duplicate

## Recommended Posts

gretty    273

Hello

I am attempting to programatically make the 2nd Monitor have a duplicate display. My function below should change the 2nd monitors display to 'duplicate display', ie, make the 2nd monitor display everything that is on the 1st/Primary monitor.

My Problem: When I run my function it successfully finds the 2nd monitor and it changes that monitors display x coordinate to 0, ie, the left of the primary monitor screen by changing the DEVMODE dmPosition.x property. Both of my 2 monitors refresh themselves(they go black then reshow their screen) but the 2nd monitor still has the extended display instead of a duplicate display.

Any ideas how I can make my 2nd Monitor have a duplicate display?

Some relevant information:
- My 2nd monitor is a LCD TV and is connected to my laptop via HDMI
- My function code is exacty the same as the example on this MSDN Page that describes how to attach a 2nd monitor without having to restart. I have changed LINE 30 though.
- I am aware I can change the display on Windows 7 using one WinAPI function call but I need my program to work on Windows 2000 and up.

// From http://support.microsoft.com/kb/308216/en-gb Title: You must restart...
{
DWORD DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
DEVMODE defaultMode;
HDC hdc;
int nWidth;
BOOL bFoundSecondary = FALSE;

hdc    = GetDC(0);
nWidth = GetDeviceCaps(hdc, HORZRES);
ReleaseDC(0, hdc);

// Initialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);

// Get display devices.
while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)) && (bFoundSecondary == FALSE))
{
ZeroMemory(&defaultMode, sizeof(DEVMODE));
defaultMode.dmSize = sizeof(DEVMODE);
if (!EnumDisplaySettings((LPTSTR)DisplayDevice.DeviceName, ENUM_REGISTRY_SETTINGS, &defaultMode)) {
printf("1\n");
return FALSE; // Store default failed
}

if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
//Found the first secondary device.
_tprintf(_T("Found the first secondary device: Name: %s, Pos: %d, Width: %d\n"), DisplayDevice.DeviceName, defaultMode.dmPosition.x, nWidth);
bFoundSecondary              = TRUE;
defaultMode.dmPosition.x = 0; // LINE CHANGED: ONLY CHANGE FROM MSDN'S CODE
defaultMode.dmFields      = DM_POSITION;
ChangeDisplaySettingsEx((LPTSTR)DisplayDevice.DeviceName, &defaultMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
_tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred

// A second call to ChangeDisplaySettings updates the monitor.
ChangeDisplaySettings(NULL, 0);
_tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred
}

// Reinitialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
DispNum++;
} // End while the display devices.

return TRUE;
}


##### Share on other sites
Vortez    2714

Well, i've been playing around with your code in VMWare using 2 monitors, and made some progress, but could't make it work either.

First of all, this line

defaultMode.dmFields = DM_POSITION;

should be

defaultMode.dmFields |= DM_POSITION;

I tryed 2-3 different flags combinaison and tryed it, but to no avail. At least you're a little closer now.

Yes, even MS make bugs.

Edit: Or im wrong and this isn't supported...

Edit2: Just realized that i can't find a way to do this in wmware normally, but i recall being able to do it via nvidia control panel, might be why it dosent work. I really have no idea, sorry. lol, at least i tried...

Edited by Vortez

##### Share on other sites
gretty    273

Thanks.

According to this answer it appears I need to focus on enabling/disabling Display Drivers to toggle duplicate / extend display.