views:

608

answers:

6

I have a C# Windows application that I want to ensure will show up on a second monitor if the user moves it to one. I need to save the main form's size, location and window state - which I've already handled - but I also need to know which screen it was on when the user closed the application.

I'm using the Screen class to determine the size of the current screen but I can't find anything on how to determine which screen the application was running on.

Edit: Thanks for the responses, everyone! I wanted to determine which monitor the window was on so I could do proper bounds checking in case the user accidentally put the window outside the viewing area or changed the screen size such that the form wouldn't be completely visible anymore.

A: 

Uhhh, there's no way to do this.

edit: why the downvote? do YOU know of a way it would be possible?

Janie
I'm not the downvoter, but you probably got it because it's a snarky response with no explanation as to why.
ryeguy
should have left your "answer" in the comment section perhaps?
Stan R.
there must be a way to do this in Win API and if so you can use that from C# via interop
zvolkov
This is all complete BS. How the hell could would a win32 call determine how many monitors are displaying the desktop with relative positions.
Janie
look at my answer Janie.
Stan R.
@Janie: I'd suggest you start with the MSDN topic MonitorFromPoint() and look at the other multiple monitor support functions, before you start insulting people by calling BS.
Ken White
Wow, I've never seen someone so fighty about something "not being possible" before. Janie, no offense, but I wouldn't want you working on any of my projects if you immediately assume it can't be done.
Jon Tackabury
@Jon: That's cool. I'll continue to make my 180K a year whether or not i'm on a project w/ you.
Janie
@Janie: I dont think this is the right place for boasting, if you know the answer then post it. If you don't, then don't post anything.
Stan R.
@Stan: No boasting, just responding to Jon's snide little remarks
Janie
@Janie: -1 for rudeness.
John Saunders
+4  A: 

If you remember the window's location and size, that will be enough. When you set the position to the previously used position, if it happened to be on the second monitor it will go back there.

For example, if you have 2 monitors, both sized 1280x1024 and you set your window's left position to be 2000px, it will appear on the second monitor (assuming the second monitor is to the right of the first.) :)

If you are worried about the second monitor not being there when the application is started the next time, you can use this method to determine if your window intersects any of the screens:

private bool isWindowVisible(Rectangle rect)
{
    foreach (Screen screen in Screen.AllScreens)
    {
     if (screen.Bounds.IntersectsWith(rect))
      return true;
    }
    return false;
}

Just pass in your window's desired location and it will tell you if it will be visible on one of the screens. Enjoy!

Jon Tackabury
agreed, but some checking at startup would be nice, so that after a reconfiguration your app won't be outside all all monitors
Henk Holterman
Actually, if someone removes the second monitor and your application will try to use Top/Left from the previous session when there were two monitors, Windows will automatically move it to the first monitor. So practically, you don't need to call isWindowVisible method.
SolutionYogi
I agree Henk - check the example I added so that you can check if your window will be visible. :)
Jon Tackabury
Thanks Jon! I used some of your code in my app.
Stephen Fletcher
A: 

Hello.

You can use the 'Screen' object: System.Windows.Forms.Screen

Start playing with something like this:

        Screen[] screens = Screen.AllScreens;
        for (int i = 0; i < screens.Length ; i++)
        {
            Debug.Print(screens[i].Bounds.ToString());
            Debug.Print(screens[i].DeviceName);
            Debug.Print(screens[i].WorkingArea.ToString());
        }

It may get you what you need

+6  A: 

You can get an array of Screens that you have using this code.

Screen[] screens = Screen.AllScreens;

You can also figure out which screen you are on, by running this code (this is the windows form you are on)

Screen screen = Screen.FromControl(this); //this is the Form class

in short check out the Screen class and static helper methods, they might help you.

MSDN Link, doesn't have much..I suggest messing around in the code by yourself.

Stan R.
Yes, people seem to forget that Form inherits from Control, so Screen.FromControl would work on it.
R. Bemrose
Maybe I should rephrase that... Form inherits from ContainerControl, which inherits from ScrollableControl, which inherits from Control.
R. Bemrose
This is completely wrong
Janie
@Janie: I am sorry you feel this way. The code I provided, does exactly what I say it does. Nothing more, nothing less. If you want to research it more, please follow the MSDN link also provided.
Stan R.
Just tested it and it doesn't work
Janie
@Janie: if you have a question with why it may not be working for you, then post it as a question and someone will surely help you out. I am sure it worked for the OP otherwise he would not have accepted the answer.
Stan R.
He was probably confused, this is not the way to do it. You can't tell which screen the form is on.
Janie
@Janie: The FromControl() method returns a Screen object. Were you thinking it returns a screen number or something? You would need to query the Bounds of the Screen to determine the location of the screen.
Tim
+1  A: 

The location of the form will tell you which screen the form is on. I don't really understand why you'd need to know what screen it is on, because if you restore it using the location you saved it should just restore to the same location (maybe you can expand as to why).

Otherwise you can do something like this:

Screen[] scr = Screen.AllScreens;
scr[i].Bounds.IntersectsWith(form.Bounds);

Each screen has a Bounds property which returns a Rectangle. You can use the IntersectsWith() function to determine if the form is within the screen.

Also, they basically provide a function that does this as well on the Screen class

Screen screen = Screen.FromControl(form);
Chap