using System;
using System.Collections.Generic;
using System.Text;
using System.Threading; // ThreadExceptionEventHandler
using System.Collections; // Collections object
using System.Drawing; // Color object
using System.Windows.Forms; // Application and MessageBox objects
using System.Diagnostics; // Process object
using System.IO; // File object
using System.Runtime.Serialization.Formatters.Soap; // had to add a reference
namespace Standard
{
///
/// This object provides getters and setters for any data that:
/// 1) more than one object might need, and
/// 2) needs to persist across program runs.
/// Actual persistent data is not stored in this object but is
/// instead stored in the "Persistent" object, which this object
/// serializes or deserializes as needed. No object should ever
/// access the "Persistent" object except this one.
///
public sealed class Model
{
static readonly Model instance=new Model();
private static Model myModel;
///
/// This suffix is appended to the exe name to create the
/// filename for the XML settings file.
///
private static string filesuffix = "_settings.xml";
///
/// This is the file specification for the XML settings file.
///
private static string settings_filespec;
///
/// This is the Model object's reference to the
/// serializable persistent settings object.
///
private static Persistent myPersistentSettings;
///
/// This method dumps the persistent settings values to the
/// log file.
///
private static void showValues()
{
string stringMe = "Model.showValues: ";
try
{
LogFile.WriteLine(stringMe +
"MainFormLeft=" + myPersistentSettings.MainFormLeft);
LogFile.WriteLine(stringMe +
"MainFormTop=" + myPersistentSettings.MainFormTop);
LogFile.WriteLine(stringMe +
"MainFormWidth=" + myPersistentSettings.MainFormWidth);
LogFile.WriteLine(stringMe +
"MainFormHeight=" + myPersistentSettings.MainFormHeight);
LogFile.WriteLine(stringMe +
"MainFormMaximized=" + myPersistentSettings.MainFormMaximized);
}
catch (Exception ex)
{ throw new Exception(stringMe + ex.Message); }
}
///
/// This method guards against the possibility of corrupted,
/// illegal values for Form position and size which could
/// allow the form to be offscreen or nonvisible to the user.
/// It tests these values and attempts to repair them if they
/// seem bad.
///
private static void validateValues()
{
string stringMe = "Model.validateValues: ";
try
{
if (myPersistentSettings.MainFormLeft < 0)
{
myPersistentSettings.MainFormLeft = 0;
LogFile.WriteLine(stringMe + "corrected MainFormLeft < 0");
}
if (myPersistentSettings.MainFormWidth < MinFormSize)
{
myPersistentSettings.MainFormWidth = MinFormSize;
LogFile.WriteLine(stringMe + "corrected MainFormWidth " +
"< MinFormSize");
}
if (myPersistentSettings.MainFormLeft > (MinScreenWidth-MinFormSize))
{
myPersistentSettings.MainFormLeft = 0;
LogFile.WriteLine(stringMe + "corrected MainFormLeft " +
"> (MinScreenWidth-MinFormSize)");
}
if (myPersistentSettings.MainFormTop < 0)
{
myPersistentSettings.MainFormTop = 0;
LogFile.WriteLine(stringMe + "corrected MainFormTop < 0");
}
if (myPersistentSettings.MainFormHeight < MinFormSize)
{
myPersistentSettings.MainFormHeight = MinFormSize;
LogFile.WriteLine(stringMe + "corrected MainFormHeight " +
"< MinFormSize");
}
if (myPersistentSettings.MainFormTop > (MinScreenHeight-MinFormSize))
{
myPersistentSettings.MainFormTop = 0;
LogFile.WriteLine(stringMe + "corrected MainFormTop > " +
"(MinScreenHeight-MinFormSize)");
}
}
catch (Exception ex)
{ throw new Exception(stringMe + ex.Message); }
}
///
/// This is the static object constructor. It runs even before
/// Main() starts to initialize this object (the Model), and so
/// it also have to open the log file and get a reference to
/// the Persistent object. If the Persistent object file exists
/// on the disk, this constructor deserializes it to retrieve
/// any values which were stored the last time the program ran.
///
static Model()
{
myPersistentSettings = Persistent.GetInstance();
string stringMe = "Model: ";
try
{
settings_filespec = Application.StartupPath + "\\" +
Application.ProductName + filesuffix;
LogFile.WriteLine(stringMe + settings_filespec);
if (File.Exists(settings_filespec))
{
// if can't deserialize, delete corrupt file
try
{
deserialize();
}
catch (Exception ex)
{
LogFile.WriteLine("couldn't deserialize: " + ex.ToString());
File.Delete(settings_filespec);
LogFile.WriteLine("deleted unserializable settings file");
}
validateValues();
}
else
{
serialize(); // create new XML file
LogFile.WriteLine(stringMe + "new settings XML file created");
}
}
catch (InvalidCastException ivex)
{ throw new Exception(stringMe + ivex.Message,ivex); }
catch (DirectoryNotFoundException dnfex)
{ throw new Exception(stringMe + dnfex.Message,dnfex); }
catch (EndOfStreamException eosex)
{ throw new Exception(stringMe + eosex.Message,eosex); }
catch (FileLoadException flex)
{ throw new Exception(stringMe + flex.Message,flex); }
catch (FileNotFoundException fnfex)
{ throw new Exception(stringMe + fnfex.Message,fnfex); }
catch (PathTooLongException ptlex)
{ throw new Exception(stringMe + ptlex.Message,ptlex); }
catch (IOException ioe)
{ throw new Exception(stringMe + ioe.Message,ioe); }
catch(Exception e)
{ throw new Exception(stringMe + e.Message,e); }
}
private Model()
{
}
///
/// returns a reference to this Singleton object
///
public static Model GetInstance()
{
return instance;
}
///
/// serializes (saves) the Persistent object (which keeps
/// track of persistent settings) to an XML file on disk
///
private static void serialize()
{
string stringMe = "Model.serialize: ";
FileStream fs = null; SoapFormatter formatter = null;
try
{
fs = new FileStream(settings_filespec, FileMode.Create);
formatter = new SoapFormatter();
formatter.Serialize(fs,myPersistentSettings);
LogFile.WriteLine(stringMe + "XML settings file updated");
fs.Close();
}
catch (DirectoryNotFoundException dnfex)
{ throw new IOException(stringMe + dnfex.Message,dnfex); }
catch (EndOfStreamException eosex)
{ throw new IOException(stringMe + eosex.Message,eosex); }
catch (FileLoadException flex)
{ throw new IOException(stringMe + flex.Message,flex); }
catch (FileNotFoundException fnfex)
{ throw new IOException(stringMe + fnfex.Message,fnfex); }
catch (PathTooLongException ptlex)
{ throw new IOException(stringMe + ptlex.Message,ptlex); }
catch (IOException ioe)
{ throw new IOException(stringMe + ioe.Message,ioe); }
catch(Exception e)
{ throw new Exception(stringMe + e.Message,e); }
finally
{
if (fs!=null) { fs.Close(); fs = null; }
if (formatter!=null) formatter = null;
}
} // end serialize
///
/// deserializes (restores) the Persistent object (which keeps
/// track of persistent settings) from an XML file on disk
///
private static void deserialize()
{
string stringMe = "Model.deserialize: ";
FileStream fs = null; SoapFormatter formatter = null;
try
{
fs = new FileStream(settings_filespec, FileMode.Open);
formatter = new SoapFormatter();
myPersistentSettings = (Persistent) (System.Object)
formatter.Deserialize(fs);
LogFile.WriteLine(stringMe +
"previous settings restored from XML file");
showValues();
fs.Close();
}
catch (DirectoryNotFoundException dnfex)
{ throw new IOException(stringMe + dnfex.Message,dnfex); }
catch (EndOfStreamException eosex)
{ throw new IOException(stringMe + eosex.Message,eosex); }
catch (FileLoadException flex)
{ throw new IOException(stringMe + flex.Message,flex); }
catch (FileNotFoundException fnfex)
{ throw new IOException(stringMe + fnfex.Message,fnfex); }
catch (PathTooLongException ptlex)
{ throw new IOException(stringMe + ptlex.Message,ptlex); }
catch (IOException ioe)
{ throw new IOException(stringMe + ioe.Message,ioe); }
catch(Exception e)
{ throw new Exception(stringMe + e.Message,e); }
finally
{
if (fs!=null) { fs.Close(); fs = null; }
if (formatter!=null) formatter = null;
}
} // end deserialize
///
/// the entry point of the application
///
[STAThread] static void Main()
{
string stringMe = "Main: ";
bool ownsMutex; Mutex mutex = null;
try
{
// refuse to run twice
mutex = new Mutex(false, Application.ProductName, out ownsMutex);
if (!ownsMutex)
{
MessageBox.Show(Application.ProductName + " is already running.");
return;
}
GC.KeepAlive(mutex);
// open an application log file
LogFile.InitLogFile();
myModel = Model.GetInstance();
// enable XP theming ("visual styles") if newer OS and
// feature available
if ((Environment.OSVersion.Version.Major >= 5) &&
(Environment.OSVersion.Version.Minor > 0))
{
if (OSFeature.Feature.IsPresent(OSFeature.Themes))
Application.EnableVisualStyles();
}
LogFile.WriteLine(stringMe + "launching main form.");
Application.Run(new MainForm());
}
catch (Exception ex)
{
string tempString = stringMe + ex.Message +
" This application will close.";
MessageBox.Show(tempString, "A problem occurred...");
LogFile.WriteLine(ex.ToString());
foreach (Form frm in Application.OpenForms)
{
frm.Close();
}
}
finally
{ LogFile.Close(); Application.Exit(); }
}
//----------------- public methods, enumerations and properties -------------
///
/// VersionShort is the shortened product version for display
/// in menus or window titles. It shows only major.minor.
///
public static string VersionShort
{
get
{
string stringMe = "Model.VersionShort: ";
try
{
string[] s = Application.ProductVersion.Split('.');
string myStr = s[0] + "." + s[1];
return myStr;
}
catch (Exception ex)
{ throw new Exception(stringMe + ex.Message); }
}
}
private static Color myBackgroundColor =
Color.FromArgb(255,168,171,232);
///
/// BackgroundColor is a System.Drawing.Color used as the
/// Background color of forms if (Background == BgType.Solid)
///
public static Color BackgroundColor
{
get { return myBackgroundColor; }
set { myBackgroundColor = value; }
}
private static Color myGradientColor1 =
Color.FromArgb(255,168,171,232);
///
/// GradientColor1 is one of two System.Drawing.Colors used for the
/// gradient on forms if (Background == Model.BgType.Gradient)
///
public static Color GradientColor1
{
get { return myGradientColor1; }
set { myGradientColor1 = value; }
}
private static Color myGradientColor2 =
Color.FromArgb(255,151,215,154);
///
/// GradientColor2 is one of two System.Drawing.Colors used for the
/// gradient on forms if (Background == Model.BgType.Gradient)
///
public static Color GradientColor2
{
get { return myGradientColor2; }
set { myGradientColor2 = value; }
}
///
/// enumeration used to specify type of form Background
/// (private field myBackground, public property
/// Background)
///
public enum BgType // used for mySettingBackState
{
Gradient,
Solid,
Image
};
///
/// Background is assigned one of the values from the
/// Model.BgType enumeration to designate whether the
/// form Backgrounds will be solid, gradient or an image.
///
public static BgType Background
{
get { return myPersistentSettings.Background; }
set
{
myPersistentSettings.Background = value;
LogFile.WriteLine("Model.Background: set to " +
myPersistentSettings.Background.ToString());
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// the main form's remembered .Left value
///
public static int MainFormLeft
{
get { return myPersistentSettings.MainFormLeft; }
set
{
myPersistentSettings.MainFormLeft = value;
LogFile.WriteLine("Model.MainFormLeft: set to " +
myPersistentSettings.MainFormLeft);
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// the main form's remembered .Top value
///
public static int MainFormTop
{
get { return myPersistentSettings.MainFormTop; }
set
{
myPersistentSettings.MainFormTop = value;
LogFile.WriteLine("Model.MainFormTop: set to " +
myPersistentSettings.MainFormTop);
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// the main form's remembered .Width value
///
public static int MainFormWidth
{
get { return myPersistentSettings.MainFormWidth; }
set
{
myPersistentSettings.MainFormWidth = value;
LogFile.WriteLine("Model.MainFormWidth: set to " +
myPersistentSettings.MainFormWidth);
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// the main form's remembered .Height value
///
public static int MainFormHeight
{
get { return myPersistentSettings.MainFormHeight; }
set
{
myPersistentSettings.MainFormHeight = value;
LogFile.WriteLine("Model.MainFormHeight: set to " +
myPersistentSettings.MainFormHeight);
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// MainFormMaximized is true is the main form should open maximized;
/// this property is not implemented yet
///
public static bool MainFormMaximized
{
get { return myPersistentSettings.MainFormMaximized; }
set
{
myPersistentSettings.MainFormMaximized = value;
LogFile.WriteLine("Model.MainFormMaximized: set to " +
myPersistentSettings.MainFormMaximized);
File.Delete(settings_filespec);
serialize(); // recreate the file
}
}
///
/// hardwired minimum form size (used to check settings validity)
///
private static readonly int myMinFormSize = 120;
///
/// minimum size the Model forces a form to be
///
public static int MinFormSize
{
get { return myMinFormSize; }
set { ; }
}
///
/// hardwired minimum screen width (used to check settings validity)
///
private static readonly int myMinScreenWidth = 640;
///
/// minimum size the Model assumes screen width to be
///
public static int MinScreenWidth
{
get { return myMinScreenWidth; }
set { ; }
}
///
/// hardwired minimum screen height (used to check settings validity)
///
private static readonly int myMinScreenHeight = 480;
///
/// minimum size the Model fassumes screen height to be
///
public static int MinScreenHeight
{
get { return myMinScreenHeight; }
set { ; }
}
} // end class
} // end namespace