GUI/MainForm.cs
author moel.mich
Wed, 16 Mar 2011 22:10:26 +0000
changeset 262 8731a1b81301
parent 253 0044b05a3094
child 265 961c07a3bd78
permissions -rw-r--r--
Fixed Issue 179.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s): Paul Werelds
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.ComponentModel;
    41 using System.Drawing;
    42 using System.IO;
    43 using System.Windows.Forms;
    44 using Aga.Controls.Tree;
    45 using Aga.Controls.Tree.NodeControls;
    46 using OpenHardwareMonitor.Hardware;
    47 using OpenHardwareMonitor.WMI;
    48 
    49 namespace OpenHardwareMonitor.GUI {
    50   public partial class MainForm : Form {
    51 
    52     private PersistentSettings settings;
    53     private UnitManager unitManager;
    54     private Computer computer;
    55     private Node root;
    56     private TreeModel treeModel;
    57     private IDictionary<ISensor, Color> sensorPlotColors = 
    58       new Dictionary<ISensor, Color>();
    59     private Color[] plotColorPalette;
    60     private SystemTray systemTray;    
    61     private StartupManager startupManager = new StartupManager();
    62     private UpdateVisitor updateVisitor = new UpdateVisitor();
    63     private SensorGadget gadget;
    64 
    65     private UserOption showHiddenSensors;
    66     private UserOption showPlot;
    67     private UserOption showValue;
    68     private UserOption showMin;
    69     private UserOption showMax;
    70     private UserOption startMinimized;
    71     private UserOption minimizeToTray;
    72     private UserOption minimizeOnClose;
    73     private UserOption autoStart;
    74     private UserOption readHddSensors;
    75     private UserOption showGadget;
    76 
    77     private WmiProvider wmiProvider;
    78 
    79     public MainForm() {      
    80       InitializeComponent();
    81 
    82       this.settings = new PersistentSettings();      
    83       this.settings.Load(Path.ChangeExtension(
    84         Application.ExecutablePath, ".config"));
    85 
    86       this.unitManager = new UnitManager(settings);
    87 
    88       // set the DockStyle here, to avoid conflicts with the MainMenu
    89       this.splitContainer.Dock = DockStyle.Fill;
    90             
    91       this.Font = SystemFonts.MessageBoxFont;
    92       treeView.Font = SystemFonts.MessageBoxFont;
    93       plotPanel.Font = SystemFonts.MessageBoxFont;
    94       treeView.RowHeight = treeView.Font.Height + 1;      
    95       
    96       nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
    97       nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
    98       nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
    99       nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
   100       nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
   101       nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
   102       nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
   103 
   104       foreach (TreeColumn column in treeView.Columns) 
   105         column.Width = Math.Max(20, Math.Min(400,
   106           settings.GetValue("treeView.Columns." + column.Header + ".Width",
   107           column.Width)));
   108 
   109       treeModel = new TreeModel();
   110       root = new Node(System.Environment.MachineName);
   111       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   112       
   113       treeModel.Nodes.Add(root);
   114       treeView.Model = treeModel;
   115 
   116       this.computer = new Computer(settings);
   117 
   118       systemTray = new SystemTray(computer, settings);
   119       systemTray.HideShowCommand += hideShowClick;
   120       systemTray.ExitCommand += exitClick;
   121 
   122       int p = (int)Environment.OSVersion.Platform;
   123       if ((p == 4) || (p == 128)) { // Unix
   124         splitContainer.BorderStyle = BorderStyle.None;
   125         splitContainer.Border3DStyle = Border3DStyle.Adjust;
   126         splitContainer.SplitterWidth = 4;
   127         treeView.BorderStyle = BorderStyle.Fixed3D;
   128         plotPanel.BorderStyle = BorderStyle.Fixed3D;
   129         gadgetMenuItem.Visible = false;
   130         minCloseMenuItem.Visible = false;
   131       } else { // Windows
   132         gadget = new SensorGadget(computer, settings, unitManager);
   133         gadget.HideShowCommand += hideShowClick;
   134 
   135         wmiProvider = new WmiProvider(computer);
   136       }          
   137 
   138       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   139       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);        
   140 
   141       computer.Open();
   142 
   143       timer.Enabled = true;
   144 
   145       plotColorPalette = new Color[13];
   146       plotColorPalette[0] = Color.Blue;
   147       plotColorPalette[1] = Color.OrangeRed;
   148       plotColorPalette[2] = Color.Green;
   149       plotColorPalette[3] = Color.LightSeaGreen;
   150       plotColorPalette[4] = Color.Goldenrod;
   151       plotColorPalette[5] = Color.DarkViolet;
   152       plotColorPalette[6] = Color.YellowGreen;
   153       plotColorPalette[7] = Color.SaddleBrown;
   154       plotColorPalette[8] = Color.RoyalBlue;
   155       plotColorPalette[9] = Color.DeepPink;
   156       plotColorPalette[10] = Color.MediumSeaGreen;
   157       plotColorPalette[11] = Color.Olive;
   158       plotColorPalette[12] = Color.Firebrick;
   159 
   160       showHiddenSensors = new UserOption("hiddenMenuItem", false,
   161         hiddenMenuItem, settings);
   162       showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
   163         treeModel.ForceVisible = showHiddenSensors.Value;
   164       };
   165 
   166       showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
   167       showPlot.Changed += delegate(object sender, EventArgs e) {
   168         splitContainer.Panel2Collapsed = !showPlot.Value;
   169         treeView.Invalidate();
   170       };
   171 
   172       showValue = new UserOption("valueMenuItem", true, valueMenuItem,
   173         settings);
   174       showValue.Changed += delegate(object sender, EventArgs e) {
   175         treeView.Columns[1].IsVisible = showValue.Value;
   176       };
   177 
   178       showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
   179       showMin.Changed += delegate(object sender, EventArgs e) {
   180         treeView.Columns[2].IsVisible = showMin.Value;
   181       };
   182 
   183       showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
   184       showMax.Changed += delegate(object sender, EventArgs e) {
   185         treeView.Columns[3].IsVisible = showMax.Value;
   186       };
   187 
   188       startMinimized = new UserOption("startMinMenuItem", false,
   189         startMinMenuItem, settings);
   190 
   191       minimizeToTray = new UserOption("minTrayMenuItem", true,
   192         minTrayMenuItem, settings);
   193       minimizeToTray.Changed += delegate(object sender, EventArgs e) {
   194         systemTray.IsMainIconEnabled = minimizeToTray.Value;
   195       };
   196 
   197       minimizeOnClose = new UserOption("minCloseMenuItem", false,
   198         minCloseMenuItem, settings);
   199 
   200       autoStart = new UserOption(null, startupManager.Startup,
   201         startupMenuItem, settings);
   202       autoStart.Changed += delegate(object sender, EventArgs e) {
   203         try {
   204           startupManager.Startup = autoStart.Value;
   205         } catch (InvalidOperationException) {
   206           MessageBox.Show("Updating the auto-startup option failed.", "Error", 
   207             MessageBoxButtons.OK, MessageBoxIcon.Error);
   208           autoStart.Value = startupManager.Startup;
   209         }
   210       };
   211 
   212       readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
   213         settings);
   214       readHddSensors.Changed += delegate(object sender, EventArgs e) {
   215         computer.HDDEnabled = readHddSensors.Value;
   216         UpdatePlotSelection(null, null);
   217       };
   218 
   219       showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
   220         settings);
   221       showGadget.Changed += delegate(object sender, EventArgs e) {
   222         if (gadget != null) 
   223           gadget.Visible = showGadget.Value;
   224       };
   225 
   226       celciusMenuItem.Checked = 
   227         unitManager.TemperatureUnit == TemperatureUnit.Celcius;
   228       fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
   229 
   230       startupMenuItem.Visible = startupManager.IsAvailable;
   231       
   232       if (startMinMenuItem.Checked) {
   233         if (!minTrayMenuItem.Checked) {
   234           WindowState = FormWindowState.Minimized;
   235           Show();
   236         }
   237       } else {
   238         Show();
   239       }
   240 
   241       // Create a handle, otherwise calling Close() does not fire FormClosed     
   242       IntPtr handle = Handle;
   243 
   244       // Make sure the settings are saved when the user logs off
   245       Microsoft.Win32.SystemEvents.SessionEnded += delegate {
   246         SaveConfiguration();
   247       };  
   248     }
   249     
   250     private void SubHardwareAdded(IHardware hardware, Node node) {
   251       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   252       node.Nodes.Add(hardwareNode);
   253       foreach (IHardware subHardware in hardware.SubHardware)
   254         SubHardwareAdded(subHardware, hardwareNode);  
   255     }
   256 
   257     private void HardwareAdded(IHardware hardware) {
   258       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   259       root.Nodes.Add(hardwareNode);
   260       foreach (IHardware subHardware in hardware.SubHardware)
   261         SubHardwareAdded(subHardware, hardwareNode);     
   262     }
   263 
   264     private void HardwareRemoved(IHardware hardware) {      
   265       List<Node> nodesToRemove = new List<Node>();
   266       foreach (Node node in root.Nodes) {
   267         HardwareNode hardwareNode = node as HardwareNode;
   268         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   269           nodesToRemove.Add(node);
   270       }
   271       foreach (Node node in nodesToRemove)
   272         root.Nodes.Remove(node);
   273     }
   274 
   275     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   276       Node node = e.Node.Tag as Node;
   277       if (node != null) {
   278         Color color;
   279         if (node.IsVisible) {
   280           SensorNode sensorNode = node as SensorNode;
   281           if (plotMenuItem.Checked && sensorNode != null &&
   282             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   283             e.TextColor = color;
   284         } else {
   285           e.TextColor = Color.DarkGray;
   286         }
   287       }
   288     }
   289 
   290     private void UpdatePlotSelection(object sender, 
   291       TreePathEventArgs e) 
   292     {
   293       List<ISensor> selected = new List<ISensor>();
   294       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   295       int colorIndex = 0;
   296       foreach (TreeNodeAdv node in treeView.AllNodes) {
   297         SensorNode sensorNode = node.Tag as SensorNode;
   298         if (sensorNode != null && 
   299           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   300           if (sensorNode.Plot) {
   301             colors.Add(sensorNode.Sensor,
   302               plotColorPalette[colorIndex % plotColorPalette.Length]);
   303             selected.Add(sensorNode.Sensor);
   304           }
   305           colorIndex++;
   306         }
   307       }
   308       sensorPlotColors = colors;
   309       plotPanel.SetSensors(selected, colors);
   310     }
   311 
   312     private void nodeTextBoxText_EditorShowing(object sender,
   313       CancelEventArgs e) 
   314     {
   315       e.Cancel = !(treeView.CurrentNode != null &&
   316         treeView.CurrentNode.Tag is SensorNode);
   317     }
   318 
   319     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   320       NodeControlValueEventArgs e) {
   321       SensorNode node = e.Node.Tag as SensorNode;
   322       e.Value = (node != null) && 
   323         (node.Sensor.SensorType == SensorType.Temperature) && 
   324         plotMenuItem.Checked;
   325     }
   326 
   327     private void exitClick(object sender, EventArgs e) {
   328       Close();
   329     }
   330 
   331     private void timer_Tick(object sender, EventArgs e) {
   332       computer.Accept(updateVisitor);
   333       treeView.Invalidate();
   334       plotPanel.Invalidate();
   335       systemTray.Redraw();
   336       if (gadget != null)
   337         gadget.Redraw();
   338 
   339       if (wmiProvider != null)
   340         wmiProvider.Update();
   341     }
   342 
   343     private void SaveConfiguration() {
   344       foreach (TreeColumn column in treeView.Columns)
   345         settings.SetValue("treeView.Columns." + column.Header + ".Width",
   346           column.Width);
   347 
   348       string fileName = Path.ChangeExtension(
   349           System.Windows.Forms.Application.ExecutablePath, ".config");
   350       try {
   351         settings.Save(fileName);
   352       } catch (UnauthorizedAccessException) {
   353         MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
   354           "The current seetings could not be saved.", 
   355           "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
   356       }
   357     }
   358 
   359     private void MainForm_Load(object sender, EventArgs e) {
   360       Rectangle newBounds = new Rectangle {
   361         X = settings.GetValue("mainForm.Location.X", Location.X),
   362         Y = settings.GetValue("mainForm.Location.Y", Location.Y),
   363         Width = settings.GetValue("mainForm.Width", 470),
   364         Height = settings.GetValue("mainForm.Height", 640)
   365       };
   366 
   367       Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
   368         int.MinValue, int.MinValue);
   369 
   370       foreach (Screen screen in Screen.AllScreens)
   371         fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
   372 
   373       Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
   374       if (intersection.Width < 20 || intersection.Height < 20 ||
   375         !settings.Contains("mainForm.Location.X")
   376       ) {
   377         newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
   378                       (newBounds.Width/2);
   379 
   380         newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
   381                       (newBounds.Height / 2);
   382       }
   383 
   384       this.Bounds = newBounds;
   385     }
   386     
   387     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   388       Visible = false;
   389       SaveConfiguration();
   390 
   391       systemTray.IsMainIconEnabled = false;
   392       timer.Enabled = false;            
   393       computer.Close();
   394       systemTray.Dispose();
   395     }
   396 
   397     private void aboutMenuItem_Click(object sender, EventArgs e) {
   398       new AboutBox().ShowDialog();
   399     }
   400 
   401     private void treeView_Click(object sender, EventArgs e) {
   402       
   403       MouseEventArgs m = e as MouseEventArgs;
   404       if (m == null || m.Button != MouseButtons.Right)
   405         return;
   406 
   407       NodeControlInfo info = treeView.GetNodeControlInfoAt(
   408         new Point(m.X, m.Y)
   409       );
   410       treeView.SelectedNode = info.Node;
   411       if (info.Node != null) {
   412         SensorNode node = info.Node.Tag as SensorNode;
   413         if (node != null && node.Sensor != null) {
   414           sensorContextMenu.MenuItems.Clear();
   415           if (node.Sensor.Parameters.Length > 0) {
   416             MenuItem item = new MenuItem("Parameters...");
   417             item.Click += delegate(object obj, EventArgs args) {
   418               ShowParameterForm(node.Sensor);
   419             };
   420             sensorContextMenu.MenuItems.Add(item);
   421           }
   422           if (nodeTextBoxText.EditEnabled) {
   423             MenuItem item = new MenuItem("Rename");
   424             item.Click += delegate(object obj, EventArgs args) {
   425               nodeTextBoxText.BeginEdit();
   426             };
   427             sensorContextMenu.MenuItems.Add(item);
   428           }
   429           if (node.IsVisible) {
   430             MenuItem item = new MenuItem("Hide");
   431             item.Click += delegate(object obj, EventArgs args) {
   432               node.IsVisible = false;
   433             };
   434             sensorContextMenu.MenuItems.Add(item);
   435           } else {
   436             MenuItem item = new MenuItem("Unhide");
   437             item.Click += delegate(object obj, EventArgs args) {
   438               node.IsVisible = true;
   439             };
   440             sensorContextMenu.MenuItems.Add(item);
   441           }
   442           sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   443           {
   444             MenuItem item = new MenuItem("Show in Tray");
   445             item.Checked = systemTray.Contains(node.Sensor);
   446             item.Click += delegate(object obj, EventArgs args) {
   447               if (item.Checked)
   448                 systemTray.Remove(node.Sensor);
   449               else
   450                 systemTray.Add(node.Sensor, true);
   451             };
   452             sensorContextMenu.MenuItems.Add(item);
   453           }
   454           if (gadget != null) {
   455             MenuItem item = new MenuItem("Show in Gadget");
   456             item.Checked = gadget.Contains(node.Sensor);
   457             item.Click += delegate(object obj, EventArgs args) {
   458               if (item.Checked) {
   459                 gadget.Remove(node.Sensor);
   460               } else {
   461                 gadget.Add(node.Sensor);
   462               }
   463             };
   464             sensorContextMenu.MenuItems.Add(item);
   465           }
   466           if (node.Sensor.Control != null) {
   467             sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   468             IControl control = node.Sensor.Control;
   469             MenuItem controlItem = new MenuItem("Control");
   470             MenuItem defaultItem = new MenuItem("Default");
   471             defaultItem.Checked = control.ControlMode == ControlMode.Default;
   472             controlItem.MenuItems.Add(defaultItem);
   473             defaultItem.Click += delegate(object obj, EventArgs args) {
   474               control.SetDefault();
   475             };
   476             MenuItem manualItem = new MenuItem("Manual");            
   477             controlItem.MenuItems.Add(manualItem);
   478             manualItem.Checked = control.ControlMode == ControlMode.Software;
   479             for (int i = 0; i <= 100; i += 5) {
   480               if (i <= control.MaxSoftwareValue &&
   481                   i >= control.MinSoftwareValue) 
   482               {
   483                 MenuItem item = new MenuItem(i + " %");
   484                 manualItem.MenuItems.Add(item);
   485                 item.Checked = control.ControlMode == ControlMode.Software &&
   486                   Math.Round(control.SoftwareValue) == i;
   487                 int softwareValue = i;
   488                 item.Click += delegate(object obj, EventArgs args) {
   489                   control.SetSoftware(softwareValue);
   490                 };
   491               }
   492             }
   493             sensorContextMenu.MenuItems.Add(controlItem);
   494           }
   495 
   496           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   497         }
   498       }
   499     }
   500 
   501     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   502       string report = computer.GetReport();
   503       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   504         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   505           w.Write(report);
   506         }
   507       }
   508     }
   509 
   510     private void SysTrayHideShow() {
   511       Visible = !Visible;
   512       if (Visible)
   513         Activate();    
   514     }
   515 
   516     protected override void WndProc(ref Message m) {
   517       const int WM_SYSCOMMAND = 0x112;
   518       const int SC_MINIMIZE = 0xF020;
   519       const int SC_CLOSE = 0xF060;
   520 
   521       if (minimizeToTray.Value && 
   522         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   523         SysTrayHideShow();
   524       } else if(minimizeOnClose.Value && 
   525         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) {
   526         /*
   527          * Apparently the user wants to minimize rather than close
   528          * Now we still need to check if we're going to the tray or not
   529          * 
   530          * Note: the correct way to do this would be to send out SC_MINIMIZE,
   531          * but since the code here is so simple,
   532          * that would just be a waste of time.
   533          */
   534         if (minimizeToTray.Value)
   535           SysTrayHideShow();
   536         else
   537           WindowState = FormWindowState.Minimized;
   538       } else {      
   539         base.WndProc(ref m);
   540       }
   541     }
   542 
   543     private void hideShowClick(object sender, EventArgs e) {
   544       SysTrayHideShow();
   545     }
   546 
   547     private void ShowParameterForm(ISensor sensor) {
   548       ParameterForm form = new ParameterForm();
   549       form.Parameters = sensor.Parameters;
   550       form.captionLabel.Text = sensor.Name;
   551       form.ShowDialog();
   552     }
   553 
   554     private void treeView_NodeMouseDoubleClick(object sender, 
   555       TreeNodeAdvMouseEventArgs e) {
   556       SensorNode node = e.Node.Tag as SensorNode;
   557       if (node != null && node.Sensor != null && 
   558         node.Sensor.Parameters.Length > 0) {
   559         ShowParameterForm(node.Sensor);
   560       }
   561     }
   562 
   563     private void celciusMenuItem_Click(object sender, EventArgs e) {
   564       celciusMenuItem.Checked = true;
   565       fahrenheitMenuItem.Checked = false;
   566       unitManager.TemperatureUnit = TemperatureUnit.Celcius;
   567     }
   568 
   569     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   570       celciusMenuItem.Checked = false;
   571       fahrenheitMenuItem.Checked = true;
   572       unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   573     }
   574 
   575     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   576     {
   577       ReportForm form = new ReportForm();
   578       form.Report = computer.GetReport();
   579       form.ShowDialog();      
   580     }
   581 
   582     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   583       computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
   584         sensor.ResetMin();
   585         sensor.ResetMax();
   586       }));
   587     }
   588 
   589     private void MainForm_MoveOrResize(object sender, EventArgs e) {
   590       if (WindowState != FormWindowState.Minimized) {
   591         settings.SetValue("mainForm.Location.X", Bounds.X);
   592         settings.SetValue("mainForm.Location.Y", Bounds.Y);
   593         settings.SetValue("mainForm.Width", Bounds.Width);
   594         settings.SetValue("mainForm.Height", Bounds.Height);
   595       }
   596     }
   597 
   598     private void resetClick(object sender, EventArgs e) {
   599       // disable the fallback MainIcon during reset, otherwise icon visibility
   600       // might be lost 
   601       systemTray.IsMainIconEnabled = false;
   602       computer.Close();
   603       computer.Open();
   604       // restore the MainIcon setting
   605       systemTray.IsMainIconEnabled = minimizeToTray.Value;
   606     }
   607   }
   608 }