How do I programmatically reposition monitors in a multiple-monitor system?
Say you’re looking to write a tool to manipulate monitor positions. What functions should you be calling?
The function to call is
ChangeDisplaySettingsEx with a
dmFields has the
DM_POSITION flag set. Put the desired upper left corner of the monitor in the
dmPosition.y fields. You’re probably also going to want to update the monitor size, which you do by setting the
DM_PELSHEIGHT flags, putting the corresponding values in the
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
EnumDisplayDevices to get all the available display devices. For each one, call
EnumDisplaySettingsEx 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
DEVMODEs, you modify the things you want to modify, and then stage the values by calling
ChangeDisplaySettingsEx to set the updated values with the
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…