How to disable a secondary monitor (with ChangeDisplaySettingsEx)?
Asked Answered
M

2

7

I'm trying to follow the instructions on MSDN given here to disable a secondary monitor.

I'm trying to use specifically this set of functions to allow compatibility with older versions of Windows.

However, I can't manage to disable a monitor. I'm running and testing this on Windows 7 x64. All I get is a flickering screen. The code definitely detects the monitor properly - I managed to change resolution and view it's display modes easily.

Here are (parts) of my code - I tried a lot of variations on the fields for DEVMODE

DEVMODE    deleteScreenMode;
ZeroMemory(&deleteScreenMode, sizeof(DEVMODE));
deleteScreenMode.dmSize = sizeof(DEVMODE);
deleteScreenMode.dmDriverExtra = 0;
deleteScreenMode.dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH;
deleteScreenMode.dmPelsWidth = 0;
deleteScreenMode.dmPelsHeight = 0;

POINTL delete;
deleteion.x=0;
deleteion.y=0;
deleteScreenMode.dmPosition = deleteion;

LONG result = ChangeDisplaySettingsEx(devName, 
                                        &deleteScreenMode,
                                        NULL,
                                        CDS_UPDATEREGISTRY,
                                        NULL);

Does anyone have experience with this? Thanks

Miaow answered 28/10, 2013 at 19:59 Comment(2)
According to the mentioned article, the dmFields mask contains more flags. Maybe the must be also set (and the corresponding fields zeroed) to detach the monitor?Burbank
I'd tried that, it didn't work. In their example they use all the possible flags - when I do that, it complains that the given mode is invalid. When I remove the DM_BITSPERPEL flag it works, but the result doesn't change. The monitors flick and remain active.Miaow
M
8

I've decided to advance into a different problem - setting a primary display - and by pure luck I've stumbled into the solution. There are 2 conditions to disable a monitor that aren't specified anywhere: 1) You can't disable the monitor dynamically - you must use CDS_UPDATEREGISTRY to write it into the registry. 2) More importantly, for some weird reason, you must first store the change in the registry (with or without CDS_NORESET, it doesn't matter), and then use again ChangeDisplaySettingsEx with NULL values to make the changes happen. This might have something to do both monitors connected to the same display device, I'm not sure...

Anyway here is the code that worked for me:

result = ChangeDisplaySettingsEx(devName, &deleteScreenMode,
                                        NULL,
                                         CDS_UPDATEREGISTRY | CDS_NORESET ,
                                        NULL);
ChangeDisplaySettingsEx (NULL, NULL, NULL, NULL, NULL);

Hope it'll help someone somewhere someday.

Miaow answered 29/10, 2013 at 18:2 Comment(0)
N
0

A similar solution is hinted at here:

http://support.microsoft.com/kb/308216

This works for attaching screens. However, even armed with that knowledge, the ChangeDisplaySettingsEx documentation on how to detach a screen is also wrong about the DevMode fields that need to be set. As you noticed, you have to set not only DM_POSITION, but also DM_PELSHEIGHT | DM_PELSWIDTH.

In Windows 7 there's a new SetDisplayConfig API, but I have no personal experience with it yet. Hopefully it's better documented!

Nonalcoholic answered 27/12, 2013 at 5:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.