Tuesday, September 22, 2009

Programming with Multiple Monitors in Windows using C#

I have a couple of prospect projects that require the application to send 2 different outputs to 2 different monitors. While I have been curious for some time about exactly how do you install more than 1 video card/monitor onto a Windows box and extend your desktop, I've never really been pushed to find out. But because of this prospect, I assigned my tech guys to do some R&D using our notebooks.

It seems that all Notebooks have 2 x video cards built-in -- one going to the LCD display, and the other going to the external VGA port. I have always assumed that it was just 1 video card and that the VGA port is just like an "extension" of the LCD. But as it turned out, Windows treats them as 2 different video cards and you have to option of whether their output to be the same, or you want it to be in "extended desktop mode".

Detecting multiple screens under C# is very trivial. The only thing that makes it a bit tedious to work with is the fact that the Display names are null-terminated (C-style). Since C# does not work natively with null-terminated strings, you have to do a little bit of conversion to C#-style strings. The example below shows how to get device info and open a modeless window which will reside on the extended desktop.

Setting the bounds of the new window to that of the extended desktop and setting the WindowState to Maximized will cause the modeless window will eat up the entire extended desktop. Of course, this simplistic demo assumes there are only at most 2 monitors. In reality, according to other postings, Windows XP and Vista officially can support up to ten (10) video cards/monitors.

allScreens = Screen.AllScreens;
foreach (Screen screen in allScreens)
string deviceName;

int length = screen.DeviceName.IndexOf("\0");
if (length == -1)
deviceName = screen.DeviceName;
deviceName = screen.DeviceName.Substring(0, length);

ExtendedForm extForm = new ExtendedForm();

Then at the constructor of the Extended Window Form:

private void ExtendedForm_Load(object sender, EventArgs e)
Screen screen;

Screen[] allScreens = Screen.AllScreens;
if (allScreens.Length == 1)
screen = allScreens[0];
screen = allScreens[1];

this.Bounds = screen.Bounds;
this.WindowState = FormWindowState.Maximized;

No comments: