tags:

views:

228

answers:

2

I have a C# application that saves its state when it is closed and then reads in the saved state when it starts up. One item that is saved is the location of the main form. Normally this works great - in my code there is a line like this that saves the location to a file that is then read back in on startup:

streamWriter.WriteLine("location:" + this.Location.X + "," + this.Location.Y);

Normally, the location coordinates look like this on my machine with multiple monitors:

location:-1069,283

Occasionally I'll see coordinates that are saved like this:

location:-32000,-32000

And then when the user brings the app back up, the form is way off the desktop and can't (easily) be retrieved by an average user.

What is happening to make the coordinates be read this way and are there suggestions to prevent this situation?

+3  A: 

The coordinates you're seeing are due to the fact that the application is minimized when it is closed. Windows "hides" your form by actually moving it from its coordinates to some ridiculously large negative X,Y coordinates.

Verified programmatically:

Output from a form app on Vista:

Current coordinates X: 184 Y: 184 *Default Location Current coordinates X: -32000 Y: -32000 *Minimized Location

From the code:

System.Diagnostics.Debug.WriteLine("Current coordinates X: " + Location.X + " Y: " + Location.Y );

To solve this i would simply check for such a value when your app is closing and not actually save it to file.

If you don't want to mess with doing math on arbitrary coordinate values you could also check the WindowState. See here on MSDN

Paul Sasik
A better solution is to keep the non-minimized coordinates in memory, and then save those when it closes.
Mark
How would I detect the non-minimized coordinates?
Dave
@Mark: Wherever you place the logic you have to check and decide whether the coordinates are minimized or not.
Paul Sasik
Check WindowState enum: http://msdn.microsoft.com/en-us/library/system.windows.forms.formwindowstate.aspx
Paul Sasik
+3  A: 

Use the RestoreBounds property on your Form.

Edit: here's a copy/paste from some of my code (could probably use a bit of cleanup, but it gets the point across). This is from my main form's FormClosing event handler:

// Save the last form state
Program.AppSettings.MainWindowFormState = this.WindowState;

// Check if the window is minimized or maximized
if ((this.WindowState == FormWindowState.Minimized) ||
    (this.WindowState == FormWindowState.Maximized))
{
    // Use the restored state values
    Program.AppSettings.MainWindowX = this.RestoreBounds.Left;
    Program.AppSettings.MainWindowY = this.RestoreBounds.Top;
    Program.AppSettings.MainWindowWidth = this.RestoreBounds.Width;
    Program.AppSettings.MainWindowHeight = this.RestoreBounds.Height;
}
else
{
    // Use the normal state values
    Program.AppSettings.MainWindowX = this.Left;
    Program.AppSettings.MainWindowY = this.Top;
    Program.AppSettings.MainWindowWidth = this.Width;
    Program.AppSettings.MainWindowHeight = this.Height;
}

And here is how to restore the state on load (remember to set your form's initial position mode to Manual to avoid flicker):

// Set the initial form state
this.WindowState = Program.AppSettings.MainWindowFormState;
this.Left = Program.AppSettings.MainWindowX;
this.Top = Program.AppSettings.MainWindowY;
this.Width = Program.AppSettings.MainWindowWidth;
this.Height = Program.AppSettings.MainWindowHeight;
Jon Seigel
Thanks, Jon. Can you point me to a URL the explains how you're using Program.AppSettings? I don't have AppSettings underneath my Program object.
Dave
That is my own custom class that manages the application's settings. As I said, this code was copy/pasted directly from one of my programs.
Jon Seigel
That's the correct and only way to do, to prevent flicker or the form location being changed before the Show event. The second part of the code has to be performed _after_ `InitializeComponent()` and _before_ the Show event, and as Jon mentioned, the `StartPosition` property of the form has to be set to `FormStartPosition.Manual`, otherwise some parameters might be changed after being set (before the Show event). A customized Xml file can be used instead of the evil Settings to avoid the very annoying directory naming scheme.
RedGlyph