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 DEVMODEs, 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…