(WinApi) ChangeDisplaySettingsEx does not work

Viewed 1659

I'm trying to write a python script to switch the primary monitor. I have 3 Monitors (one is plugged into my i5's graphics chip, and 2 are plugged into a ATI HD7870)

I wrote the following script:

import win32api as w
import win32con as c

i = 0
workingDevices = []

def setPrimary(id):
    global workingDevices
    return w.ChangeDisplaySettingsEx(
        workingDevices[id].DeviceName,
        w.EnumDisplaySettings(
            workingDevices[id].DeviceName,
            c.ENUM_CURRENT_SETTINGS
            ),
        c.CDS_SET_PRIMARY | c.CDS_UPDATEREGISTRY | c.CDS_RESET) \
        == c.DISP_CHANGE_SUCCESSFUL

while True:
    try:
        Device = w.EnumDisplayDevices(None, i, 1)
        if Device.StateFlags & c.DISPLAY_DEVICE_ATTACHED_TO_DESKTOP: #Attached to desktop
            workingDevices.append(Device)

        i += 1
    except:
        break

print("Num Devices: ", len(workingDevices))

for dev in workingDevices:
    print("Name: ", dev.DeviceName)

Invoking it leads to:

In [192]: %run test.py
Num Devices:  3
Name:  \\.\DISPLAY1
Name:  \\.\DISPLAY2
Name:  \\.\DISPLAY7

In [193]: setPrimary(0)
Out[193]: True

In [194]: setPrimary(1)
Out[194]: True

In [195]: setPrimary(2)
Out[195]: True

So far it looks great, but the problem is: nothing changes. My monitors flicker shortly because of the CDS_RESET but the primary screen does not change, although ChangeDisplaySettingsEx returns DISP_CHANGE_SUCCESSFUL

Does anyone have an Idea why? (I use Python 3.5.1 and PyWin32 build 220)

PS I use 1 as the third arg for EnumDisplayDevices because the msdn states it should be set to one, although the PyWin help says it should be set to 0. But the behaviour of the script does not change independent of this value beeing one or zero

1 Answers
Related