Say you’re looking to write a tool to manipulate monitor positions. What functions should you be calling?
The function to call is ChangeÂDisplayÂSettingsÂEx
with a DEVMODE
whose dmFields
has the DM_POSITION
flag set. Put the desired upper left corner of the monitor in the dmPosition.x
and dmPosition.y
fields. You’re probably also going to want to update the monitor size, which you do by setting the DM_PELSWIDTH
and DM_PELSHEIGHT
flags, putting the corresponding values in the dmPelsWidth
and dmPelsHeight
members. To remove a monitor from the desktop, set the position to (0,0) and the width and height to zero.
The overall pattern is to use EnumÂDisplayÂDevices
to get all the available display devices. For each one, call EnumÂDisplayÂSettingsÂEx
to get the current DEVMODE
for each monitor, using ENUM_
to get whatever the monitor setting is right now, or ENUM_
to get the saved settings. (The current settings may be different from the registry settings if the display is in a temporary mode, such as when playing a fullscreen DirectX game.)
After you gather all of the DEVMODE
s, you modify the things you want to modify, and then stage the values by calling ChangeÂDisplayÂSettingsÂEx
to set the updated values with the CDS_
and CDS_
flags.
Finally, once you’re done setting all the coordinates, perform a final
ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
to apply all the settings at once.
MSDN provides a sample function that detaches all secondary monitors to give you an idea of how the whole thing fits together.
If programmatically repositioning monitors actually moved the physical monitors around too, I’d be impressed. And a little scared…