My primary user-target are user with multiple screens.
My application should overlay all those screens. This is easy for users with screens standing next to each other, primary screen left. Then i can just set my program's this.Left = 0 (same with Top) and set the width to the screens combined width.
Unfortunately not ever user has the same setup, so I have to make some dynamic code, that will place the window correctly on every setup.
What if the user has the primary screen to the right? What if he has the screens vertically? What if he has different resolutions and/or different scaling factors (DPI, 100%, 125%, ...) on each screen?
Can someone help me out write a C# Method that will place my window correctly to overlay every monitor? Thanks!
This function will calculate the total number of screens connected and will give you the Dimensions.
public System.Drawing.Size GetTotalArea()
{
System.Drawing.Size SizeYouNeed = new Size(0,0);
foreach (var screen in Screen.AllScreens)
{
SizeYouNeed.Height+=screen.WorkingArea.Height;
SizeYouNeed.Width +=screen.WorkingArea.Width;
}
return SizeYouNeed;
}
Related
I am trying to get the CurrentMonitor property of NativeWindowSettings to change which monitor it creates the window on. I'm trying to display on my secondary monitor, here is what I have:
var nativeWindowSettings = new NativeWindowSettings()
{
Size = new OpenTK.Mathematics.Vector2i(800, 600),
Title = "My Window",
Flags = OpenTK.Windowing.Common.ContextFlags.ForwardCompatible,
CurrentMonitor = new Monitors.GetMonitors()[1].Handle, //problem
};
using (var window = new Game(GameWindowSettings.Default, nativeWindowSettings))
{
window.Run();
}
I've tried creating a new Monitor Handle and assigning it to that, and I've tried creating a new MonitorHandle using the pointer from the second monitor in the array of monitors.
CurrentMonitor = new MonitorHandle(Monitors.GetMonitors()[1].Handle.Pointer),
It depends on your OS. Not all window systems give you the ability to specify which screen a newly-created window will appear on, and not all of them are going to pay attention to that parameter either. Your mileage may vary, as they say. You didn’t specify which OS you’re on, so I’m going to assume for the rest of this that it’s some flavor of Microsoft Windows.
On MS Windows, you don’t get to specify which screen your new window appears on without also specifying exactly where on that screen the window should appear: If you let Windows pick the coordinates, it’s going to put the window on the primary screen every time, exactly as you’ve seen it doing.
So the right way to go about it, at least on MS Windows, is to first find out the virtual coordinates of the screen (the MonitorInfo) that you want to create the window on. You can choose from its ClientArea (the virtual coordinates of the entire screen) or its WorkArea (the virtual coordinates of the usable part of that screen, minus things like the taskbar). In either case, each MonitorInfo’s rectangle will be a unique chunk of virtual screen space that doesn’t overlap that of any of the others.
Once you’ve found the rectangle of the screen you want to create the window on, you just specify a Location in the NativeWindowSettings that’s on that screen, inside the coordinates of its ClientArea or WorkArea: Possibly in the top corner, or, if you want to be a bit more clever, you can do some math and center the window in that virtual rectangle. The only thing you can’t easily do is the OS’s “cascading” behavior, where your window will be given a new position that’s sort-of distinct from the others on the screen but not really centered and not really in the top corner either; that behavior is built-in inside the window system, and there’s no way to directly access it or influence it.
But that’s otherwise it: You don’t specify the monitor: You specify a Location that’s on the monitor, and then the window will appear there. That’s not really an OpenTK thing, either: That’s just how Microsoft Windows does a multi-monitor setup.
I have three monitors/screens of different sizes/resolutions setup as an extended view, all wired to the same NVIDIA graphic card. And from left to right:
Screen#0: 2400*1080
Screen#1: 1920x1080
Screen#2: 1920*1080
My application has three separate Windows, where I respectively position each Window to the corresponding monitor/screen with the following code
window00.Left = System.Windows.Forms.Screen.AllScreens[0].WorkingArea.Left;
window01.Left = System.Windows.Forms.Screen.AllScreens[1].WorkingArea.Left;
window02.Left = System.Windows.Forms.Screen.AllScreens[2].WorkingArea.Left;
window00.WindowState = System.Windows.WindowState.Maximized;
window01.WindowState = System.Windows.WindowState.Maximized;
window02.WindowState = System.Windows.WindowState.Maximized;
I only get the 3rd windows (window02) position to the right most screen properly (Screen#02), but both the 1st and 2nd windows (window00 & window01) stack and maximized to the first screen (Screen#00), leaving the middle Screen#01 empty displaying the background desktop environment, regardless if I set WindowsState.Maximized or Normal.
Even if I workaround the problem through offsetting window01 position by the width of Screen#00 to get all three windows position properly to their corresponding screens, if I maximize Windows.State, window01 still jumps back to Screen#00.
Why is this happening and why does the window not position or maximized to its WorkingArea it assigned to? Could it be due to WPF application using Forms properties?
I have a winform (c#, let's say 250px by 250px) that needs to stay in one location on the screen regardless of screen resolution i.e 800x600, 1920x1080 etc. The Winform itself contains only one element - a picturebox so what's inside really doesn't matter (no need to worry about fonts, etc.). I just need it to stick in one place on the screen from one monitor to another.
Any ideas? Thanks in advance.
Could you use one of these?
1) WindowsState = Maximized (then you dont worry, it always takes whole screen)
2) StartPosition = CenterScreen (then it always shows as centered), or CenterParent to center within parent form
3) Location = in this case you would have to do some math to get screen size, your form size than based on that center it but I dont see point of using this considering that StartPosition does it already for you.
Hope that helps
Ok, so in order to get the window at a fixed location given in % of the screen size, you need the screen size (e.g. using this answer), compute the desired position, and set it as the window-location.
Since you need to do it at startup, you could do it before you show the window, or maybe best inside a Frame.Loaded event handler.
Is there a way to make make a windows form application full screen and black out your secondary monitors? So the main display is on your primary display and all your other monitors are just completely black?
You can use the Screen class which give you informations about the current active screens.
// Form myFrm
Rectangle r = new Rectangle();
foreach (Screen s in Screen.AllScreens)
{
if ( s != Screen.CurrentScreen ) // Blackout only the secondary screens
r = Rectangle.Union(r, s.Bounds);
}
myFrm.Top = r.Top;
myFrm.Left = r.Left;
myFrm.Width = r.Width;
myFrm.Height = r.Height;
myFrm.TopMost = true; // This will bring your window in front of all other windows including the taskbar
I can think of one way, and that would be to find out how many monitors there are on the computer, and their layout relative to each other, then create your primary window at 0,0, maximize it and set it to be TopMost, then do the same for the other displays, placing them at the screen locations corresponding to the top left of each monitor of the computer.
The only thing I can think of that would benefit from this in a WinForms environment is an app designed to give a test; the app would cover the entire desktop (except the taskbar; you'd have to disable the Start menu) and pretty much ensure that the user couldn't look at anything except the testing program. It will give you a minimal performance advantage.
Most of the apps that black out all the monitors except the main display are basically using DirectX to control the screen directly (through the lower-level interface to the graphics card). If you're using WinForms to make your program, you're about 50 levels of abstraction above using DirectX.
One way would be to create a second form in your application. One that, when given a set of dimensions, will open without border or menu and with the background set to black.
When your application runs, enumerate your monitors (count them to see how many) and find their dimensions. Your primary one will start at 0,0.
Then spawn a copy of that second form for each of your monitors (except your primary one) and give that form the dimensions of the monitor. They will then turn each screen black.
You will need to remember to keep a handle to each of the forms and terminate them when you terminate your main form.
I made an application on 1366x768 resolution which is my laptop's current resolution, being a beginner, i din't care about the resolution issues.
When i took that application and executed it on a lower resolution PC , then all was messed up. The form was going somewhere else, most of its part hidden.
So, please help me to how to make my winform resolution independent, or how to get the current screen resolution and set it into my winform so that it changes itself accordingly.
The property
Screen.PrimaryScreen.WorkingArea
is very useful for form sizing and positioning.
For example this code:
this.Width = Screen.PrimaryScreen.WorkingArea.Width/2;
this.Height = Screen.PrimaryScreen.WorkingArea.Height/2;
this.Top = (Screen.PrimaryScreen.WorkingArea.Top + Screen.PrimaryScreen.WorkingArea.Height)/4;
this.Left = (Screen.PrimaryScreen.WorkingArea.Left + Screen.PrimaryScreen.WorkingArea.Width)/4;
(The Screen class is a member of System.Windows.Forms namespace)
will place the form in which it is executed in the middle of the screen and size it to half the screen.
The WorkingArea var is used to exclude stuff like the task bar and other docked items on the desktop when calculating the size of the screen.
Hope this helps.
See here: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/1be40692-80fa-42ba-b316-9fe13a935b4f/ and here: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/d5f2cd8d-d24d-4574-ba3a-96e22e3d1b56/
General approach is to start with the min resolution you'll be working with. Then you can scale your forms up (using proper docking and anchors).