Independent Displays

A disabled monitor (one that is removed or detached from the desktop), is still available for use by specially programmed applications. Three important points to remember with independent displays:

  • each monitor has its own coordinate system rooted at 0,0
  • the window manager is not available. This means that you can't create windows on an independent display
  • the mouse has no access to independent displays
Sample

This sample draws a diagonal black line on a white background on \\.\DISPLAY2 (assuming this display exists and has been disabled).

DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsEx(_T("\\\\.\\DISPLAY2"), ENUM_REGISTRY_SETTINGS, &dm, 0);
HDC dc = CreateDC(_T("\\\\.\\DISPLAY2"), 0, 0, &dm);
HBRUSH oldBrush = static_cast<HBRUSH>(SelectObject(dc, GetStockObject(WHITE_BRUSH)));
Rectangle(dc, 0, 0, dm.dmPelsWidth, dm.dmPelsHeight);
MoveToEx(dc, 0, 0, 0);
LineTo(dc, dm.dmPelsWidth, dm.dmPelsHeight);
SelectObject(dc, oldBrush);
DeleteDC(dc);

Basically, you create a DC for the desired display, then draw on it using GDI functions. I'm using EnumDisplaySettingsEx to get the last-used display settings for the display. You can also specify different width, height and bits per pixel settings by modifying dm.

Important: on Windows 2000/XP, you have to call the Unicode version of CreateDC, otherwise the call will fail. To do this, either call CreateDCW explicitly, or compile for Unicode by defining UNICODE and _UNICODE.

Limitations and Issues

Single-chipset dualhead cards on Windows 98/Me and XP: due to a limitation in the operating system support for this type of display adapter, it is not possible to create independent displays on such a card. CreateDC will fail and GetLastError returns ERROR_INVALID_PRINTER_NAME.

Creating an independent display may require reboot: if CreateDC fails, reboot the system and try again. I'm not sure why this is required, but during testing I found that after rebooting the call to CreateDC succeeded. It is not necessary to leave the display disabled when rebooting.

Independent displays can't be used through all graphics APIs: GDI+ and OpenGL aren't supported, DirectX only on Windows 98/Me.

Independent display may be re-attached to desktop after reboot: due to a bug in Windows or the display driver, the call to CreateDC causes the Attach.ToDesktop registry value being set to 1 again, so the display is being treated as attached to the desktop after the next reboot.

Applications

Due to the limitations and issues mentioned above, I would only recommend use of independent displays if there is no other solution.

UltraMon™ 2.0 Beta 6 used independent displays for the mirroring feature, but since Beta 7 independent displays are simulated using the new Virtual Independent Displays feature. This feature is available to external applications, see the UltraMon SDK for more information.