GUI/MainForm.cs
author moel.mich
Tue, 09 Mar 2010 22:27:10 +0000
changeset 79 9cdbe1d8d12a
parent 70 dc69dc4d7512
child 82 91edecb084a1
permissions -rw-r--r--
Changed the CPU clock calculation. If no invariant TSC is available, then the max CPU clock is estimated at startup under load, otherwise an average over one second is used.
     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):
    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.Configuration;
    42 using System.Drawing;
    43 using System.Text;
    44 using System.Windows.Forms;
    45 using Aga.Controls.Tree;
    46 using Aga.Controls.Tree.NodeControls;
    47 using OpenHardwareMonitor.Hardware;
    48 using OpenHardwareMonitor.Utilities;
    49 
    50 namespace OpenHardwareMonitor.GUI {
    51   public partial class MainForm : Form {
    52 
    53     private Computer computer = new Computer();
    54     private Node root;
    55     private TreeModel treeModel;
    56     private IDictionary<ISensor, Color> sensorPlotColors = 
    57       new Dictionary<ISensor, Color>();
    58     private Color[] plotColorPalette;
    59     private SensorSystemTray sensorSystemTray;
    60     private NotifyIcon notifyIcon;
    61 
    62     public MainForm() {      
    63       InitializeComponent();
    64       this.Font = SystemFonts.MessageBoxFont;
    65       treeView.Font = SystemFonts.MessageBoxFont;
    66       plotPanel.Font = SystemFonts.MessageBoxFont;
    67       
    68       nodeCheckBox.IsVisibleValueNeeded += 
    69         new EventHandler<NodeControlValueEventArgs>(
    70           nodeCheckBox_IsVisibleValueNeeded);
    71       nodeCheckBox.CheckStateChanged += 
    72         new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
    73       nodeTextBoxText.DrawText += 
    74         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    75       nodeTextBoxValue.DrawText +=
    76         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    77       nodeTextBoxMin.DrawText +=
    78         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    79       nodeTextBoxMax.DrawText +=
    80         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    81       nodeTextBoxLimit.DrawText += 
    82         new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
    83 
    84       if (Utilities.Config.Contains("mainForm.Location.X")) {
    85         int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
    86         x = x < 0 ? 0 : x;
    87         int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
    88         y = y < 0 ? 0 : y;
    89         this.Location = new Point(x, y);
    90       } else {
    91         StartPosition = FormStartPosition.CenterScreen;
    92       }
    93 
    94       Width = Utilities.Config.Get("mainForm.Width", Width);
    95       Height = Utilities.Config.Get("mainForm.Height", Height);
    96          
    97       treeModel = new TreeModel();
    98       root = new Node(System.Environment.MachineName);
    99       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   100       
   101       treeModel.Nodes.Add(root);
   102       treeView.Model = treeModel;
   103       
   104       notifyIcon = new NotifyIcon();
   105       notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
   106       notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
   107       notifyIcon.Text = "Open Hardware Monitor";      
   108       notifyIcon.DoubleClick += new EventHandler(this.restoreClick);
   109 
   110       sensorSystemTray = new SensorSystemTray(computer);
   111 
   112       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   113       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   114       computer.Open();
   115 
   116       plotColorPalette = new Color[14];
   117       plotColorPalette[0] = Color.Blue;
   118       plotColorPalette[1] = Color.OrangeRed;
   119       plotColorPalette[2] = Color.Green;
   120       plotColorPalette[3] = Color.LightSeaGreen;
   121       plotColorPalette[4] = Color.Goldenrod;
   122       plotColorPalette[5] = Color.DarkViolet;
   123       plotColorPalette[6] = Color.YellowGreen;
   124       plotColorPalette[7] = Color.SaddleBrown;
   125       plotColorPalette[8] = Color.Gray;
   126       plotColorPalette[9] = Color.RoyalBlue;
   127       plotColorPalette[10] = Color.DeepPink;
   128       plotColorPalette[11] = Color.MediumSeaGreen;
   129       plotColorPalette[12] = Color.Olive;
   130       plotColorPalette[13] = Color.Firebrick;
   131 
   132       plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
   133       minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
   134       maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
   135       limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
   136 
   137       startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false); 
   138       minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
   139       hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
   140 
   141       voltMenuItem.Checked = Config.Get(voltMenuItem.Name, true);
   142       clocksMenuItem.Checked = Config.Get(clocksMenuItem.Name, true);
   143       loadMenuItem.Checked = Config.Get(loadMenuItem.Name, true);
   144       tempMenuItem.Checked = Config.Get(tempMenuItem.Name, true);
   145       fansMenuItem.Checked = Config.Get(fansMenuItem.Name, true);
   146       flowsMenuItem.Checked = Config.Get(flowsMenuItem.Name, true);
   147      
   148       timer.Enabled = true;
   149 
   150       if (startMinMenuItem.Checked) {
   151         if (minTrayMenuItem.Checked) {
   152           notifyIcon.Visible = true;
   153         } else {
   154           WindowState = FormWindowState.Minimized;
   155           Show();
   156         }
   157       } else {
   158         Show();
   159       }
   160 
   161       // Create a handle, otherwise calling Close() does not fire FormClosed     
   162       IntPtr handle = Handle;
   163     }
   164 
   165     private void SubHardwareAdded(IHardware hardware, Node node) {
   166       Node hardwareNode = new HardwareNode(hardware);
   167       node.Nodes.Add(hardwareNode);
   168       foreach (IHardware subHardware in hardware.SubHardware)
   169         SubHardwareAdded(subHardware, hardwareNode);  
   170     }
   171 
   172     private void HardwareAdded(IHardware hardware) {
   173       Node hardwareNode = new HardwareNode(hardware);
   174       root.Nodes.Add(hardwareNode);
   175       foreach (IHardware subHardware in hardware.SubHardware)
   176         SubHardwareAdded(subHardware, hardwareNode);     
   177     }
   178 
   179     private void HardwareRemoved(IHardware hardware) {      
   180       List<Node> nodesToRemove = new List<Node>();
   181       foreach (Node node in root.Nodes) {
   182         HardwareNode hardwareNode = node as HardwareNode;
   183         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   184           nodesToRemove.Add(node);
   185       }
   186       foreach (Node node in nodesToRemove)
   187         root.Nodes.Remove(node);
   188     }
   189 
   190     private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
   191       SensorNode sensorNode = e.Node.Tag as SensorNode;
   192       if (sensorNode != null) 
   193         e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
   194     }
   195 
   196     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
   197       if (!plotMenuItem.Checked)
   198         return;      
   199 
   200       SensorNode sensorNode = e.Node.Tag as SensorNode;
   201       if (sensorNode != null) {
   202         Color color;
   203         if (sensorPlotColors.TryGetValue(sensorNode.Sensor, out color)) 
   204           e.TextColor = color;        
   205       }
   206     }
   207 
   208     private void UpdatePlotSelection(object sender, 
   209       TreePathEventArgs e) 
   210     {
   211       List<ISensor> selected = new List<ISensor>();
   212       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   213       int colorIndex = 0;
   214       foreach (TreeNodeAdv node in treeView.AllNodes) {
   215         SensorNode sensorNode = node.Tag as SensorNode;
   216         if (sensorNode != null && 
   217           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   218           if (sensorNode.Plot) {
   219             colors.Add(sensorNode.Sensor,
   220               plotColorPalette[colorIndex % plotColorPalette.Length]);
   221             selected.Add(sensorNode.Sensor);
   222           }
   223           colorIndex++;
   224         }
   225       }
   226       sensorPlotColors = colors;
   227       plotPanel.SetSensors(selected, colors);
   228     }
   229 
   230     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   231       NodeControlValueEventArgs e) {
   232       SensorNode node = e.Node.Tag as SensorNode;
   233       e.Value = (node != null) && 
   234         (node.Sensor.SensorType == SensorType.Temperature) && 
   235         plotMenuItem.Checked;
   236     }
   237 
   238     private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
   239       Close();      
   240     }
   241 
   242     private void timer_Tick(object sender, EventArgs e) {
   243       
   244       #if !DEBUG
   245       try {
   246       #endif
   247         computer.Update();        
   248       #if !DEBUG
   249       } catch (Exception exception) {
   250         CrashReport.Save(exception);
   251         Close();
   252       }
   253       #endif
   254             
   255       treeView.Invalidate();
   256       plotPanel.Invalidate();
   257       sensorSystemTray.Redraw();
   258     }
   259 
   260     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   261             
   262       Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
   263       Config.Set(minMenuItem.Name, minMenuItem.Checked);
   264       Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
   265       Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
   266 
   267       Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
   268       Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
   269       Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
   270 
   271       Config.Set(voltMenuItem.Name, voltMenuItem.Checked);
   272       Config.Set(clocksMenuItem.Name, clocksMenuItem.Checked);
   273       Config.Set(loadMenuItem.Name, loadMenuItem.Checked);
   274       Config.Set(tempMenuItem.Name, tempMenuItem.Checked);
   275       Config.Set(fansMenuItem.Name, fansMenuItem.Checked);
   276       Config.Set(flowsMenuItem.Name, flowsMenuItem.Checked);
   277 
   278       if (WindowState != FormWindowState.Minimized) {
   279         Config.Set("mainForm.Location.X", Location.X);
   280         Config.Set("mainForm.Location.Y", Location.Y);
   281         Config.Set("mainForm.Width", Width);
   282         Config.Set("mainForm.Height", Height);
   283       }
   284            
   285       sensorSystemTray.Dispose();
   286       notifyIcon.Dispose();
   287       computer.Close();
   288     }
   289 
   290     private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
   291       new AboutBox().ShowDialog();
   292     }
   293 
   294     private void plotToolStripMenuItem_CheckedChanged(object sender, 
   295       EventArgs e) 
   296     {
   297       splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
   298       treeView.Invalidate();
   299     }
   300 
   301     private void valueToolStripMenuItem_CheckedChanged(object sender, 
   302       EventArgs e) 
   303     {
   304       treeView.Columns[1].IsVisible = valueToolStripMenuItem.Checked;
   305     }
   306 
   307     private void minToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   308     {
   309       treeView.Columns[2].IsVisible = minMenuItem.Checked;
   310     }
   311 
   312     private void maxToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   313     {
   314       treeView.Columns[3].IsVisible = maxMenuItem.Checked;
   315     }
   316 
   317     private void limitToolStripMenuItem_CheckedChanged(object sender, 
   318       EventArgs e) {
   319       treeView.Columns[4].IsVisible = limitMenuItem.Checked;
   320     }
   321 
   322     private void treeView_Click(object sender, EventArgs e) {
   323       
   324       MouseEventArgs m = e as MouseEventArgs;
   325       if (m == null || m.Button != MouseButtons.Right)
   326         return;
   327 
   328       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   329       if (info.Control == null) {
   330         columnsContextMenuStrip.Show(treeView, m.X, m.Y);
   331       } else {
   332         SensorNode node = info.Node.Tag as SensorNode;
   333         if (node != null && node.Sensor != null) {
   334 
   335           sensorContextMenuStrip.Items.Clear();
   336           if (node.Sensor.Parameters.Length > 0) {
   337             ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
   338             item.Click += delegate(object obj, EventArgs args) {
   339               ShowParameterForm(node.Sensor);
   340             };
   341             sensorContextMenuStrip.Items.Add(item);
   342           }
   343           if (sensorSystemTray.Contains(node.Sensor)) {
   344             ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
   345             item.Click += delegate(object obj, EventArgs args) {
   346               sensorSystemTray.Remove(node.Sensor);
   347             };
   348             sensorContextMenuStrip.Items.Add(item);
   349           } else {
   350             ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
   351             item.Click += delegate(object obj, EventArgs args) {
   352               sensorSystemTray.Add(node.Sensor, true);
   353             };
   354             sensorContextMenuStrip.Items.Add(item);
   355           }
   356           sensorContextMenuStrip.Show(treeView, m.X, m.Y);
   357         }
   358       }
   359     }
   360 
   361     private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
   362       computer.SaveReport(new Version(Application.ProductVersion));      
   363     }
   364 
   365     private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
   366       EventArgs e) 
   367     {
   368       computer.HDDEnabled = hddMenuItem.Checked;
   369       UpdateSensorTypeChecked(null, null);
   370       UpdatePlotSelection(null, null);      
   371     }
   372 
   373     private void UpdateSensorTypeVisible(Node node) {
   374       HardwareNode hardwareNode = node as HardwareNode;
   375       if (hardwareNode == null)
   376         return;
   377 
   378       hardwareNode.SetVisible(SensorType.Voltage, voltMenuItem.Checked);
   379       hardwareNode.SetVisible(SensorType.Clock, clocksMenuItem.Checked);
   380       hardwareNode.SetVisible(SensorType.Load, loadMenuItem.Checked);
   381       hardwareNode.SetVisible(SensorType.Temperature, tempMenuItem.Checked);
   382       hardwareNode.SetVisible(SensorType.Fan, fansMenuItem.Checked);
   383       hardwareNode.SetVisible(SensorType.Flow, flowsMenuItem.Checked);
   384 
   385       foreach (Node n in node.Nodes)
   386         UpdateSensorTypeVisible(n);
   387     }
   388 
   389     private void UpdateSensorTypeChecked(object sender, EventArgs e) {          
   390       foreach (HardwareNode node in root.Nodes) 
   391         UpdateSensorTypeVisible(node);
   392     }
   393 
   394     private void ToggleSysTray() {
   395       if (notifyIcon.Visible) {
   396         Visible = true;
   397         notifyIcon.Visible = false;
   398         Activate(); 
   399       } else {
   400         notifyIcon.Visible = true;
   401         Visible = false;           
   402       }
   403     }
   404 
   405     protected override void WndProc(ref Message m) {
   406       const int WM_SYSCOMMAND = 0x112;
   407       const int SC_MINIMIZE = 0xF020;
   408       if (minTrayMenuItem.Checked && 
   409         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   410         ToggleSysTray();
   411       } else {      
   412         base.WndProc(ref m);
   413       }
   414     }
   415 
   416     private void restoreClick(object sender, EventArgs e) {
   417       ToggleSysTray();
   418     }
   419 
   420     private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
   421       ToolStripMenuItem item = sender as ToolStripMenuItem;
   422       if (item == null)
   423         return;
   424 
   425       ISensor sensor = item.Owner.Tag as ISensor;
   426       if (sensor == null)
   427         return;
   428 
   429       sensorSystemTray.Remove(sensor);
   430     }
   431 
   432     private void ShowParameterForm(ISensor sensor) {
   433       ParameterForm form = new ParameterForm();
   434       form.Parameters = sensor.Parameters;
   435       form.captionLabel.Text = sensor.Name;
   436       form.ShowDialog();
   437     }
   438 
   439     private void treeView_NodeMouseDoubleClick(object sender, 
   440       TreeNodeAdvMouseEventArgs e) {
   441       SensorNode node = e.Node.Tag as SensorNode;
   442       if (node != null && node.Sensor != null && 
   443         node.Sensor.Parameters.Length > 0) {
   444         ShowParameterForm(node.Sensor);
   445       }
   446     }
   447   }
   448 }