Showing Winforms on dual-screen setup - c#

I have a winforms application in C#, with about 10 forms to navigate through.
On all of them, I have set StartPosition as CenterScreen but I use a laptop with a second screen plugged in.
Now the application starts randomly on one of my screens. Also even if the app is on one screen, MessageBoxes pop up on the second one. How can I set the application to always start at the main screen, the one set as "1" in Windows.
I also want to bind the application to the screen it is showing at so that MessageBoxes would appear on the same screen as the app. Another thing I would like to have is so that new forms would show on the same position as previous forms, not going back to the screen where the application started.
What should I use to control the positions of the forms?
I tried changing StartPosition to CenterParent, but that doesn't seem to change anything.

Try this out on starting page ( first form):
private void MyForm_Load(object sender, EventArgs e)
{
this.Location = Screen.AllScreens[0].WorkingArea.Location;
this.StartPosition = FormStartPosition.CenterScreen;
}
More information here : Showing a Windows form on a secondary monitor?
This question is about showing program on secondary screen. just change 1 index to 0 on arrays if you used answers of that.
Edit:
Just for emphasize Bryce Wagner comment for other people read this question :
If you're calling it from a form or user control, you'll want to call MessageBox.Show(this, "Message") instead.

Combining all answers here and in similar questions, the working solution for showing app on primary screen is this:
private void FormLogin_Load(object sender, EventArgs e)
{
this.Location = Screen.AllScreens[0].WorkingArea.Location;
ReallyCenterToScreen();
}
protected void ReallyCenterToScreen()
{
Screen screen = Screen.FromControl(this);
Rectangle workingArea = screen.WorkingArea;
this.Location = new Point()
{
X = Math.Max(workingArea.X, workingArea.X + (workingArea.Width - this.Width) / 2),
Y = Math.Max(workingArea.Y, workingArea.Y + (workingArea.Height - this.Height) / 2)
};
}
And to keep the MessageBoxes on the center screen is this:
MessageBox.Show(this, "Message")
Sources are the comment of #Bryce Wagner to my question, the answer from #Mohamad Shahrestani and from this question answer by #Sarsur.A

I have a laptop with a second screen. Windows 10 is in "Extend" mode. None of the code examples helped with my dialog ignoring the manual location.
It turns out that NVidia has some helpful options in their driver. One will decide for you where you want your form or your dialog. If your code just doesn't seem to behave, try the "nView Desktop Manager" -> "Windows Manager" -> "Dialog box repositioning" and Open windows on settings.

Related

C# Switch off or cover duplicated monitor

I'm developing an app in C#. This app will run on a PC and also in a WACOM tablet, which is a duplicated monitor of the PC.
I want to switch off or cover the tablet with an image because the client can't see the beginning and the end of the process. When the time is right, the tablet will turn on or the screensaver will be removed so that the client can interact and, once the client's actions are finished, the WACOM tablet returns to the initial state. How can I do this?
I've been searching and I've found how to switch off the principal monitor but I don't know how to switch off only the tablet. Also some kind of screensaver would be right, but I didn't found how to put an image only in one screen.
You didn't mention the framework you are working, assuming you can reference WinForms, here is a way to show a form maximized on a specific screen:
System.Windows.Forms.Screen[] screens;
screens = System.Windows.Forms.Screen.AllScreens;
System.Windows.Forms.Screen selectedScreen = screens[1]; // choose your preffered monitor
// Sets the form to show maximized on the selected screen:
form.Left = currentScreen.Bounds.Width;
form.Top = currentScreen.Bounds.Height;
form.StartPosition = FormStartPosition.Manual;
form.Location = currentScreen.Bounds.Location;
Point p = new Point(currentScreen.Bounds.Location.X, currentScreen.Bounds.Location.Y);
form.Location = p;
form.WindowState = FormWindowState.Maximized;
form.Show();
If you disable form borders and have a PictureBox docked to "Fill" displaying your selected image you will achieve your intended goal and cover your tablet screen with an image.

Form Position (set OnLoad) different when program installed

I have a Windows Forms application that I use the following code to dock it to the lower-right side of the screen when it is launched:
protected override void OnLoad(EventArgs e)
{
var s = Screen.FromPoint(this.Location);
this.Location = new Point(s.WorkingArea.Right - this.Width,
s.WorkingArea.Height - this.Height);
base.OnLoad(e);
}
When I am in Visual Studio debug mode, this works like a charm. When I build an installer and install the application (on the same dev box) and run it, the coordinates are slightly different and the form is not perfectly docked in the corner. So I stuck this in the OnLoad:
MessageBox.Show(this.Location.X + "x" + this.Location.Y);
In development mode it displays 1355x720 but when I install it displays 1365x730
Why the discrepency? Obviously I could just subtract 10 for my code to work but I would like an explanation for this behavior.
Update:
This machine is Windows 8.1 Pro 64-bit with multiple monitors.
It is the form size that is different (not Screen.WorkingArea). In development mode the form size shows 245x140 but when I install it shows 235x130
I am also unable to give the form focus. There is a textbox on the form that receives focus onload. It has the blinking caret, but I cannot type until I physically click on the textbox. This again only happens when I install it; works fine when run from VS. I suspect this is related to the form position going off the screen edge.
The form has TopMost set to True

fullscreen is not always functioning

Good day, I have a winform that can set full screen. But sometimes it's not. It is sometimes 3/4 of the screen but sometimes it is full screen. Below is my Code. Anybody knows why it's not always fullscreen....?
private void Form1_Load(object sender, EventArgs e)
{
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Width = Screen.PrimaryScreen.WorkingArea.Width;
Height = Screen.PrimaryScreen.WorkingArea.Height;
}
When I run it in my pc. Its fine. But when it is in the production. I saw it did not go well. But sometimes it is ok.
By the way, I want my taskbar to be seen. If I set FormWindowState.Maximized, my taskbar would not be seen.
Thank you.
The issue is that the WorkingArea is not the same with Full Screen. WorkingArea is relative, not the common way of forcing full screen.
There are a couple of ways to attempt to force the full screen.
One of the most popular way to force fill is by setting WindowsState to Maximized (also here and here - quite popular) combined with setting TopMost property to true.
private void Form1_Load(object sender, EventArgs e)
{
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
}
Alternatively, less popularly, you could also use Screen.Bounds (but may not be absolute too, try to put additional TopMost = true)
And finally, you could also using WorkingArea with conditional statement. To debug and see what is the WorkingArea size in you production PC, you could use GetWorkingArea method. This way, you can debug what is the working area in the production PC and if it is not full screen comparing to the size of the PC, you could force is to full screen. Not so efficient though...
Here is more explanation on working area vs screen area to help you making decisions.
Edit: with bar to be seen, what I could think of as another way to do this is by Get Screen Size. See:
How can I get the active screen dimensions?
Then you should limit the maximum dimension of your form (y/x-axis) such that you have room for your bar - that is, to be little less than the screen size in one of the axis. Then, on form load or other related events, you could control the position of your WinForm such that you won't block your bar.
See StartupPosition property:
C# window positioning
Screen.PrimaryScreen.WorkingArea only gets the screen's working area.
I think you need to change it to
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
You just need to set the WindowState to Maximized at run-time:
WindowState = FormWindowState.Maximized;
Or at design-time, using the WindowState property of the form.

Cascade windows in a non MDI C++/CLI application

I would like to implement a cascade layout in my application.
I cannot use FormStartPosition.WindowsDefaultLocation as per the below answer
C# Cascading forms without mdi parent?
Even though cascading is achieved using this approach, each time windows are coming at different different locations.
I want to display windows at fixed positions preferably starting from CentreScreen and going towards the bottomroght direction
Extra Info: This is a tray icon application and each form is displayed Modally by calling ShowDialog().
please help!!
Thanks & Regards,
Rohini
If you are going to show the windows modally Form.ShowDialog() I'm not really sure a cascade layout is really necessary. Just set StartPosition = FormStartPosition.CenterParent and you should be good to go.
If you really insist on doing a manual cascade then set Form.StartPosition to FormStartPosition.Manual. This enables you to define the starting point of the Form through the Form.Location property.
Typically, you should do this overriding Form.OnLoad(EventArgs e) and working your starting position based on the position of Form.Owner
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.Owner != null)
{
this.Location = .... // offset this.Owner.Location
}
}
Note that Form.Location is in global screen coordinates though it doesn't make a difference as you are working with offsets.

Replace Windows Shell or Restrict application window size

I'm working on an application for home based users. And this application involves completely replacing windows explorer for a custom application.
I would like to mimic the behavior of the taskbar. For example, when you click the maximize button in Notepad, it does not overlap the taskbar.
I already tried to use the api to AppBar however, AppBar api does not work when windows explorer is not running and other windows overlap my taskbar.
Any idea how I can do this? If I can restrict the size of maximized windows when ever helps me. The problem is that other applications are not always written by me.
I found an example using an win32 api SystemParametersInfo.
This way I can define an area where the other applications will fit and leave an space to my form even if other applications is maximized.
Link on github
public static void MakeNewDesktopArea()
{
// Save current Working Area size
m_rcOldDesktopRect.left = SystemInformation.WorkingArea.Left;
m_rcOldDesktopRect.top = SystemInformation.WorkingArea.Top;
m_rcOldDesktopRect.right = SystemInformation.WorkingArea.Right;
m_rcOldDesktopRect.bottom = SystemInformation.WorkingArea.Bottom;
// Make a new Workspace
WinAPI.RECT rc;
rc.left = SystemInformation.VirtualScreen.Left + 150;
rc.top = SystemInformation.VirtualScreen.Top; // We reserve the 24 pixels on top for our taskbar
rc.right = SystemInformation.VirtualScreen.Right;
rc.bottom = SystemInformation.VirtualScreen.Bottom - 101;
WinAPI.SystemParametersInfo((int)WinAPI.SPI.SPI_SETWORKAREA, 0, ref rc, 0);
}

Categories