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