GUI/MainForm.cs
author moel.mich
Sat, 20 Feb 2010 19:51:10 +0000
changeset 56 5cb7eb5bf628
parent 42 47385d4fc990
child 57 142907c75be4
permissions -rw-r--r--
Improved Winbond temperature reading. Temperatures create by adding PECI Agent values (delta to TCC Activation Temperature) to a (possibly uncalibrated) TBase are not read. Direct reading temperatures from sensor report register if available. Added lower bound for temperatures on Winbond chips. Nvidia GPUs are now displayed even if they do not have any sensors.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@1
    40
using System.ComponentModel;
moel@1
    41
using System.Configuration;
moel@1
    42
using System.Drawing;
moel@1
    43
using System.Text;
moel@1
    44
using System.Windows.Forms;
moel@1
    45
using Aga.Controls.Tree;
moel@1
    46
using Aga.Controls.Tree.NodeControls;
moel@1
    47
using OpenHardwareMonitor.Hardware;
moel@28
    48
using OpenHardwareMonitor.Utilities;
moel@1
    49
moel@1
    50
namespace OpenHardwareMonitor.GUI {
moel@1
    51
  public partial class MainForm : Form {
moel@1
    52
moel@28
    53
    private Computer computer = new Computer();
moel@1
    54
    private Node root;
moel@1
    55
    private TreeModel treeModel;
moel@1
    56
    private IDictionary<ISensor, Color> sensorPlotColors = 
moel@1
    57
      new Dictionary<ISensor, Color>();
moel@1
    58
    private Color[] plotColorPalette;
moel@40
    59
    private SensorSystemTray sensorSystemTray;
moel@40
    60
    private NotifyIcon notifyIcon;
moel@1
    61
moel@28
    62
    public MainForm() {      
moel@1
    63
      InitializeComponent();
moel@1
    64
      this.Font = SystemFonts.MessageBoxFont;
moel@1
    65
      treeView.Font = SystemFonts.MessageBoxFont;
moel@1
    66
      plotPanel.Font = SystemFonts.MessageBoxFont;      
moel@1
    67
      
moel@1
    68
      nodeCheckBox.IsVisibleValueNeeded += 
moel@1
    69
        new EventHandler<NodeControlValueEventArgs>(
moel@1
    70
          nodeCheckBox_IsVisibleValueNeeded);
moel@1
    71
      nodeCheckBox.CheckStateChanged += 
moel@1
    72
        new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
moel@1
    73
      nodeTextBoxText.DrawText += 
moel@1
    74
        new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
moel@1
    75
      nodeTextBoxValue.DrawText +=
moel@1
    76
        new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
moel@1
    77
      nodeTextBoxMin.DrawText +=
moel@1
    78
        new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
moel@1
    79
      nodeTextBoxMax.DrawText +=
moel@1
    80
        new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
moel@1
    81
      nodeTextBoxLimit.DrawText += 
moel@1
    82
        new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
moel@1
    83
moel@1
    84
      if (Utilities.Config.Contains("mainForm.Location.X")) {
moel@1
    85
        int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
moel@1
    86
        x = x < 0 ? 0 : x;
moel@1
    87
        int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
moel@1
    88
        y = y < 0 ? 0 : y;
moel@1
    89
        this.Location = new Point(x, y);
moel@1
    90
      } else {
moel@1
    91
        StartPosition = FormStartPosition.CenterScreen;
moel@1
    92
      }
moel@1
    93
moel@1
    94
      Width = Utilities.Config.Get("mainForm.Width", Width);
moel@1
    95
      Height = Utilities.Config.Get("mainForm.Height", Height);
moel@1
    96
         
moel@1
    97
      treeModel = new TreeModel();
moel@1
    98
      root = new Node(System.Environment.MachineName);
moel@1
    99
      root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
moel@1
   100
      
moel@1
   101
      treeModel.Nodes.Add(root);
moel@1
   102
      treeView.Model = treeModel;
moel@40
   103
      
moel@40
   104
      notifyIcon = new NotifyIcon();
moel@40
   105
      notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
moel@40
   106
      notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
moel@40
   107
      notifyIcon.Text = "Open Hardware Monitor";      
moel@40
   108
      notifyIcon.DoubleClick += new EventHandler(this.restoreClick);
moel@40
   109
moel@40
   110
      sensorSystemTray = new SensorSystemTray(computer);
moel@1
   111
moel@28
   112
      computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
moel@28
   113
      computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
moel@28
   114
      computer.Open();
moel@28
   115
moel@1
   116
      plotColorPalette = new Color[14];
moel@1
   117
      plotColorPalette[0] = Color.Blue;
moel@1
   118
      plotColorPalette[1] = Color.OrangeRed;
moel@1
   119
      plotColorPalette[2] = Color.Green;
moel@1
   120
      plotColorPalette[3] = Color.LightSeaGreen;
moel@1
   121
      plotColorPalette[4] = Color.Goldenrod;
moel@1
   122
      plotColorPalette[5] = Color.DarkViolet;
moel@1
   123
      plotColorPalette[6] = Color.YellowGreen;
moel@1
   124
      plotColorPalette[7] = Color.SaddleBrown;
moel@1
   125
      plotColorPalette[8] = Color.Gray;
moel@1
   126
      plotColorPalette[9] = Color.RoyalBlue;
moel@1
   127
      plotColorPalette[10] = Color.DeepPink;
moel@1
   128
      plotColorPalette[11] = Color.MediumSeaGreen;
moel@1
   129
      plotColorPalette[12] = Color.Olive;
moel@1
   130
      plotColorPalette[13] = Color.Firebrick;
moel@1
   131
moel@28
   132
      plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
moel@28
   133
      minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
moel@28
   134
      maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
moel@28
   135
      limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
moel@1
   136
moel@55
   137
      startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false); 
moel@28
   138
      minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
moel@28
   139
      hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
moel@1
   140
moel@28
   141
      voltMenuItem.Checked = Config.Get(voltMenuItem.Name, true);
moel@28
   142
      clocksMenuItem.Checked = Config.Get(clocksMenuItem.Name, true);
moel@28
   143
      loadMenuItem.Checked = Config.Get(loadMenuItem.Name, true);
moel@28
   144
      tempMenuItem.Checked = Config.Get(tempMenuItem.Name, true);
moel@28
   145
      fansMenuItem.Checked = Config.Get(fansMenuItem.Name, true);
moel@28
   146
     
moel@55
   147
      timer.Enabled = true;
moel@55
   148
moel@55
   149
      if (startMinMenuItem.Checked) {
moel@55
   150
        if (minTrayMenuItem.Checked) {
moel@55
   151
          notifyIcon.Visible = true;
moel@55
   152
        } else {
moel@55
   153
          WindowState = FormWindowState.Minimized;
moel@55
   154
          Show();
moel@55
   155
        }
moel@55
   156
      } else {
moel@55
   157
        Show();
moel@55
   158
      }
moel@1
   159
    }
moel@1
   160
moel@28
   161
    private void HardwareAdded(IHardware hardware) {
moel@28
   162
      root.Nodes.Add(new HardwareNode(hardware));
moel@1
   163
    }
moel@1
   164
moel@28
   165
    private void HardwareRemoved(IHardware hardware) {      
moel@1
   166
      List<Node> nodesToRemove = new List<Node>();
moel@28
   167
      foreach (Node node in root.Nodes) {
moel@28
   168
        HardwareNode hardwareNode = node as HardwareNode;
moel@28
   169
        if (hardwareNode != null && hardwareNode.Hardware == hardware)
moel@28
   170
          nodesToRemove.Add(node);
moel@28
   171
      }
moel@1
   172
      foreach (Node node in nodesToRemove)
moel@1
   173
        root.Nodes.Remove(node);
moel@1
   174
    }
moel@1
   175
moel@1
   176
    private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
moel@1
   177
      SensorNode sensorNode = e.Node.Tag as SensorNode;
moel@1
   178
      if (sensorNode != null) 
moel@1
   179
        e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
moel@1
   180
    }
moel@1
   181
moel@1
   182
    private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
moel@1
   183
      if (!plotMenuItem.Checked)
moel@1
   184
        return;      
moel@1
   185
moel@1
   186
      SensorNode sensorNode = e.Node.Tag as SensorNode;
moel@1
   187
      if (sensorNode != null) {
moel@1
   188
        Color color;
moel@1
   189
        if (sensorPlotColors.TryGetValue(sensorNode.Sensor, out color)) 
moel@1
   190
          e.TextColor = color;        
moel@1
   191
      }
moel@1
   192
    }
moel@1
   193
moel@1
   194
    private void UpdatePlotSelection(object sender, 
moel@1
   195
      TreePathEventArgs e) 
moel@1
   196
    {
moel@1
   197
      List<ISensor> selected = new List<ISensor>();
moel@1
   198
      IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
moel@1
   199
      int colorIndex = 0;
moel@1
   200
      foreach (TreeNodeAdv node in treeView.AllNodes) {
moel@1
   201
        SensorNode sensorNode = node.Tag as SensorNode;
moel@1
   202
        if (sensorNode != null && 
moel@1
   203
          sensorNode.Sensor.SensorType == SensorType.Temperature) {
moel@1
   204
          if (sensorNode.Plot) {
moel@1
   205
            colors.Add(sensorNode.Sensor,
moel@1
   206
              plotColorPalette[colorIndex % plotColorPalette.Length]);
moel@1
   207
            selected.Add(sensorNode.Sensor);
moel@1
   208
          }
moel@1
   209
          colorIndex++;
moel@1
   210
        }
moel@1
   211
      }
moel@1
   212
      sensorPlotColors = colors;
moel@1
   213
      plotPanel.SetSensors(selected, colors);
moel@1
   214
    }
moel@1
   215
moel@1
   216
    private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
moel@1
   217
      NodeControlValueEventArgs e) {
moel@1
   218
      SensorNode node = e.Node.Tag as SensorNode;
moel@1
   219
      e.Value = (node != null) && 
moel@1
   220
        (node.Sensor.SensorType == SensorType.Temperature) && 
moel@1
   221
        plotMenuItem.Checked;
moel@1
   222
    }
moel@1
   223
moel@1
   224
    private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
moel@1
   225
      Close();
moel@1
   226
    }
moel@1
   227
moel@1
   228
    private void timer_Tick(object sender, EventArgs e) {
moel@1
   229
      
moel@1
   230
      #if !DEBUG
moel@1
   231
      try {
moel@1
   232
      #endif
moel@28
   233
        computer.Update();        
moel@1
   234
      #if !DEBUG
moel@1
   235
      } catch (Exception exception) {
moel@28
   236
        CrashReport.Save(exception);
moel@1
   237
        Close();
moel@1
   238
      }
moel@1
   239
      #endif
moel@1
   240
            
moel@1
   241
      treeView.Invalidate();
moel@1
   242
      plotPanel.Invalidate();
moel@40
   243
      sensorSystemTray.Redraw();
moel@1
   244
    }
moel@1
   245
moel@1
   246
    private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
moel@28
   247
            
moel@28
   248
      Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
moel@28
   249
      Config.Set(minMenuItem.Name, minMenuItem.Checked);
moel@28
   250
      Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
moel@28
   251
      Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
moel@1
   252
moel@55
   253
      Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
moel@28
   254
      Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
moel@28
   255
      Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
moel@28
   256
moel@28
   257
      Config.Set(voltMenuItem.Name, voltMenuItem.Checked);
moel@28
   258
      Config.Set(clocksMenuItem.Name, clocksMenuItem.Checked);
moel@28
   259
      Config.Set(loadMenuItem.Name, loadMenuItem.Checked);
moel@28
   260
      Config.Set(tempMenuItem.Name, tempMenuItem.Checked);
moel@28
   261
      Config.Set(fansMenuItem.Name, fansMenuItem.Checked);
moel@1
   262
moel@14
   263
      if (WindowState != FormWindowState.Minimized) {
moel@28
   264
        Config.Set("mainForm.Location.X", Location.X);
moel@28
   265
        Config.Set("mainForm.Location.Y", Location.Y);
moel@28
   266
        Config.Set("mainForm.Width", Width);
moel@28
   267
        Config.Set("mainForm.Height", Height);
moel@14
   268
      }
moel@42
   269
           
moel@40
   270
      sensorSystemTray.Dispose();
moel@40
   271
      notifyIcon.Dispose();
moel@28
   272
      computer.Close();
moel@1
   273
    }
moel@1
   274
moel@1
   275
    private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
moel@1
   276
      new AboutBox().ShowDialog();
moel@1
   277
    }
moel@1
   278
moel@1
   279
    private void plotToolStripMenuItem_CheckedChanged(object sender, 
moel@1
   280
      EventArgs e) 
moel@1
   281
    {
moel@1
   282
      splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
moel@1
   283
      treeView.Invalidate();
moel@1
   284
    }
moel@1
   285
moel@1
   286
    private void valueToolStripMenuItem_CheckedChanged(object sender, 
moel@1
   287
      EventArgs e) 
moel@1
   288
    {
moel@1
   289
      treeView.Columns[1].IsVisible = valueToolStripMenuItem.Checked;
moel@1
   290
    }
moel@1
   291
moel@1
   292
    private void minToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
moel@1
   293
    {
moel@1
   294
      treeView.Columns[2].IsVisible = minMenuItem.Checked;
moel@1
   295
    }
moel@1
   296
moel@1
   297
    private void maxToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
moel@1
   298
    {
moel@1
   299
      treeView.Columns[3].IsVisible = maxMenuItem.Checked;
moel@1
   300
    }
moel@1
   301
moel@1
   302
    private void limitToolStripMenuItem_CheckedChanged(object sender, 
moel@1
   303
      EventArgs e) {
moel@1
   304
      treeView.Columns[4].IsVisible = limitMenuItem.Checked;
moel@1
   305
    }
moel@1
   306
moel@1
   307
    private void treeView_Click(object sender, EventArgs e) {
moel@1
   308
      
moel@1
   309
      MouseEventArgs m = e as MouseEventArgs;
moel@1
   310
      if (m == null || m.Button != MouseButtons.Right)
moel@1
   311
        return;
moel@1
   312
moel@1
   313
      NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
moel@28
   314
      if (info.Control == null) {
moel@1
   315
        columnsContextMenuStrip.Show(treeView, m.X, m.Y);
moel@40
   316
      } else {
moel@40
   317
        SensorNode node = info.Node.Tag as SensorNode;
moel@40
   318
        if (node != null && node.Sensor != null) {
moel@40
   319
moel@40
   320
          sensorContextMenuStrip.Items.Clear();
moel@40
   321
          if (sensorSystemTray.Contains(node.Sensor)) {
moel@40
   322
            ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
moel@40
   323
            item.Click += delegate(object obj, EventArgs args) {
moel@40
   324
              sensorSystemTray.Remove(node.Sensor);
moel@40
   325
            };
moel@40
   326
            sensorContextMenuStrip.Items.Add(item);
moel@40
   327
          } else {
moel@40
   328
            ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
moel@40
   329
            item.Click += delegate(object obj, EventArgs args) {
moel@42
   330
              sensorSystemTray.Add(node.Sensor, true);
moel@40
   331
            };
moel@40
   332
            sensorContextMenuStrip.Items.Add(item);
moel@40
   333
          }
moel@40
   334
          sensorContextMenuStrip.Show(treeView, m.X, m.Y);
moel@40
   335
        }
moel@40
   336
      }
moel@1
   337
    }
moel@1
   338
moel@1
   339
    private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
moel@28
   340
      computer.SaveReport(new Version(Application.ProductVersion));      
moel@1
   341
    }
moel@1
   342
moel@1
   343
    private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
moel@1
   344
      EventArgs e) 
moel@1
   345
    {
moel@28
   346
      computer.HDDEnabled = hddMenuItem.Checked;
moel@28
   347
      UpdateSensorTypeChecked(null, null);
moel@28
   348
      UpdatePlotSelection(null, null);      
moel@1
   349
    }
moel@1
   350
moel@1
   351
    private void UpdateSensorTypeChecked(object sender, EventArgs e) {
moel@1
   352
      foreach (HardwareNode node in root.Nodes) {
moel@1
   353
        node.SetVisible(SensorType.Voltage, voltMenuItem.Checked);
moel@1
   354
        node.SetVisible(SensorType.Clock, clocksMenuItem.Checked);
moel@24
   355
        node.SetVisible(SensorType.Load, loadMenuItem.Checked);
moel@1
   356
        node.SetVisible(SensorType.Temperature, tempMenuItem.Checked);
moel@1
   357
        node.SetVisible(SensorType.Fan, fansMenuItem.Checked);
moel@1
   358
      }
moel@27
   359
    }
moel@27
   360
moel@27
   361
    private void ToggleSysTray() {
moel@55
   362
      if (notifyIcon.Visible) {
moel@27
   363
        Visible = true;
moel@27
   364
        notifyIcon.Visible = false;
moel@55
   365
        Activate(); 
moel@55
   366
      } else {
moel@55
   367
        notifyIcon.Visible = true;
moel@55
   368
        Visible = false;           
moel@27
   369
      }
moel@27
   370
    }
moel@27
   371
moel@27
   372
    protected override void WndProc(ref Message m) {
moel@27
   373
      const int WM_SYSCOMMAND = 0x112;
moel@27
   374
      const int SC_MINIMIZE = 0xF020;
moel@28
   375
      if (minTrayMenuItem.Checked && 
moel@28
   376
        m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
moel@27
   377
        ToggleSysTray();
moel@27
   378
      } else {      
moel@27
   379
        base.WndProc(ref m);
moel@27
   380
      }
moel@27
   381
    }
moel@27
   382
moel@28
   383
    private void restoreClick(object sender, EventArgs e) {
moel@28
   384
      ToggleSysTray();
moel@27
   385
    }
moel@27
   386
moel@40
   387
    private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
moel@40
   388
      ToolStripMenuItem item = sender as ToolStripMenuItem;
moel@40
   389
      if (item == null)
moel@40
   390
        return;
moel@40
   391
moel@40
   392
      ISensor sensor = item.Owner.Tag as ISensor;
moel@40
   393
      if (sensor == null)
moel@40
   394
        return;
moel@40
   395
moel@40
   396
      sensorSystemTray.Remove(sensor);
moel@40
   397
    }
moel@1
   398
  }
moel@1
   399
}