Basics

The following is an overview of the API functions used with multiple monitors. A sample is included that demonstrates obtaining information about a multi-monitor system (available in C++ and Visual Basic). For detailed information on API functions, see the multi-monitor topic in the MSDN Library.

EnumDisplayDevices

This is the essential multi-monitor function, allows you to enumerate all installed displays. It also returns the device name for each display, which is used by the EnumDisplaySettings and ChangeDisplaySettingsEx functions. See the sample for more on this function.

GetMonitorInfo

Returns information about a monitor's screen and workspace area, given a monitor handle. Monitor handles can be obtained from EnumDisplayMonitors and the MonitorFrom... functions.

I mainly use this function to get the workspace area of a monitor (the area not occupied by desktop toolbars), information about the screen area can also be obtained from EnumDisplaySettings.

Tip: if you have a monitor's position on the desktop, you can easily get a monitor handle by calling MonitorFromPoint.

Important: monitor handles are only available for enabled monitors, you can't call GetMonitorInfo for a disabled monitor. The handles for all monitors change when the desktop configuration is changed (a monitor is disabled or enabled), they may also be different after every reboot.

EnumDisplayMonitors

Enumerates all monitors by repeatedly calling a user-defined function. Your function receives a handle for each monitor. You can also enumerate all monitors intersecting a specified device context or rectangle.

EnumDisplaySettings, EnumDisplaySettingsEx

Used to get information about a display, such as position and resolution. The device name required by this function is obtained from EnumDisplayDevices.

Important: device names can be anything, you should always use EnumDisplayDevices. That said, device names commonly are of the form \\.\DISPLAYx, where x is a one-based number. Dualhead cards on Windows 98/Me usually use a naming scheme like \\.\DISPLAY1\Unit0 or \\.\DISPLAY1\U0, where the unit is the zero-based number of the VGA output.

To get information about a disabled monitor, use the ENUM_REGISTRY_SETTINGS mode, ENUM_CURRENT_SETTINGS will fail. Note that on Windows 9x, position information for disabled monitors is invalid.

ChangeDisplaySettingsEx

This function is used to change settings such as position and resolution of a display. This function can be complicated to use, and behavior is not consistent between Win9x and NT-based platforms. For an easy way to change display settings, take a look at UltraMon™.

GetSystemMetrics

The following metrics are used with multiple monitors:

  • SM_CMONITORS: returns the number of monitors attached to the desktop. If a monitor has been disabled, it won't show up in this count
  • SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN: the coordinates of the top-left corner of the desktop. Remember that these coordinates can be negative on a multi-monitor system
  • SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN: returns the width and height of the desktop. These are the dimensions of the bounding rectangle of all monitors
  • SM_SAMEDISPLAYFORMAT: returns TRUE if all monitors have the same pixel format, FALSE otherwise. The same colordepth doesn't necessarily mean the same pixel format: the bits making up a single pixel could be arranged differently (RGB vs BGR, differing 16-bit formats: 565 vs 555)

Please note that SM_CXSCREEN and SM_CYSCREEN return the width and height of the primary monitor only. This breaks some fullscreen applications such as screen savers, which use this function to get the size of the desktop. Of course these applications would have been broken anyway, because they assume that the top-left corner of the desktop is at 0,0.

MonitorFromPoint, MonitorFromRect, MonitorFromWindow

Returns a handle to the monitor containing the given point, rectangle or window. In the case of rectangles and windows, a handle to the monitor with the largest area of intersection is returned.

Sample application

The sample application displays information about installed monitors: