Reputation: 4278
I am trying to debug a strange issue with users that have LogMeIn installed. After a few days, some of my dialogs that my app opens can end up offscreen. If I could reliable detect that, I could programmatically move the dialogs back where they are visible again.
Note: this has to work for multiple monitors and use the win32 API. However, if you know how to do it from .NET I can probably extrapolate from there...
Update: For the curious, the bug mentioned above has to do with wxWidgets. If you run a wxWidgets application, then walk away and let your screen saver go, then log in remotely with LogMeIn, then try to open a dialog from your app, you will have trouble if you use wxDisplay::GetFromPoint(pos) or wxWindowBase::Center() to position the dialog.
Upvotes: 5
Views: 3109
Reputation: 11
This is a long time ago now, but Marin Plante's answer got me what I needed, so I wrote a simple extension method:
public static class WindowLocation
{
public static Boolean VisibleOnScreen(this Form form)
{
foreach (Screen screen in Screen.AllScreens)
{
if (screen.Bounds.Contains(form.Bounds)) return true;
}
return false;
}
}
May help someone else!
Upvotes: 0
Reputation: 8828
See also How can I get the active screen dimensions?
This is the code I used in the form constructor it's a quickie to move the form to a visible screen after you undock your laptop or whatever it is you did to make some screen real estate go away. Refine for your own consumption.
if (!Screen.FromControl(this).Bounds.Contains(this.Location))
{
this.DesktopLocation = new Point(100,100);
}
Upvotes: 1
Reputation: 8035
Whatever you do, please account for multiple monitors which may have coordinates thousands of pixels away from (0,0) in any direction. I hate it when an app forces itself back into another screen, frequently messing up any full-screen games I may be in at the time.
Upvotes: 1
Reputation: 6529
Simply use MonitorFromWindow with the MONITOR_DEFAULTTONULL flag. If the return value is null, your window is not visible. You can subsequently pass MONITOR_DEFAULTTONEAREST to be able to reposition your window on the nearest monitor.
Upvotes: 9
Reputation: 340506
All the basics on multiple monitor support from June 1997 Microsoft Systems Journal:
Positioning Objects on a Multiple Display Setup:
Upvotes: 2
Reputation: 30428
It looks like GetMonitorInfo() is the Win32 equivalent of Danny's suggestion. I'm not sure how you'd go about getting an HMONITOR for all of the monitors on the system, but it looks like the example linked from the documentation has some ways of doing it.
Upvotes: 0
Reputation: 4703
In .NET, I would iterate on each Screen in Screen.AllScreen, then either call screen.Bounds.Contains() passing your form's rectangle if you want to make sure all of your window is within bounds(*), or call screen.Bounds.IntersectsWith() if you only want to make sure at least a portion of your form is visible.
(*) Not being fully within one screen bounds does not mean it's not within the total screens' bounds. You could also call Rectangle.Union on each screen bounds to create a single rectangle to test your form's rectangle against, but then you must watch out if screen bounds are not of the same size, since the englobing rectangle is not fully visible either.
That was the longer answer. The shorter one is: There is no easy way I know of.
Upvotes: 1
Reputation: 15588
In .NET, you use the Screen.PrimaryScreen.WorkingArea structure to get the bounds of the primary screen (Screen.Screens[x].WorkingArea for other monitors, I think), and then use the Left and Top properties of the window to find out where the window is (if it's off the screen, Top and Left will be bigger than [Screen].Width and .Height.
Upvotes: 1
Reputation: 549
Hmm. This might not help, but when I did VB, you could do screen.width and screen.height, and then window.x and window.y...
Of course, I don't know how that works with multiple monitors.
Upvotes: -1