Added an event handler to save the configuration when the user logs off without closing the application first (http://blogs.msdn.com/b/oldnewthing/archive/2008/04/21/8413175.aspx), because FormClosed is not called in that case.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
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
9 http://www.mozilla.org/MPL/
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.
15 The Original Code is the Open Hardware Monitor code.
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.
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.
39 using System.Collections.Generic;
40 using System.ComponentModel;
41 using System.Configuration;
45 using System.Windows.Forms;
46 using Aga.Controls.Tree;
47 using Aga.Controls.Tree.NodeControls;
48 using OpenHardwareMonitor.Hardware;
49 using OpenHardwareMonitor.Utilities;
51 namespace OpenHardwareMonitor.GUI {
52 public partial class MainForm : Form {
54 private Computer computer = new Computer();
56 private TreeModel treeModel;
57 private IDictionary<ISensor, Color> sensorPlotColors =
58 new Dictionary<ISensor, Color>();
59 private Color[] plotColorPalette;
60 private SensorSystemTray sensorSystemTray;
61 private NotifyIcon notifyIcon;
62 private StartupManager startupManager = new StartupManager();
63 private UpdateVisitor updateVisitor = new UpdateVisitor();
66 InitializeComponent();
67 this.Font = SystemFonts.MessageBoxFont;
68 treeView.Font = SystemFonts.MessageBoxFont;
69 plotPanel.Font = SystemFonts.MessageBoxFont;
71 nodeCheckBox.IsVisibleValueNeeded +=
72 new EventHandler<NodeControlValueEventArgs>(
73 nodeCheckBox_IsVisibleValueNeeded);
74 nodeCheckBox.CheckStateChanged +=
75 new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
76 nodeTextBoxText.DrawText +=
77 new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
78 nodeTextBoxValue.DrawText +=
79 new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
80 nodeTextBoxMin.DrawText +=
81 new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
82 nodeTextBoxMax.DrawText +=
83 new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
84 nodeTextBoxLimit.DrawText +=
85 new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
87 if (Utilities.Config.Contains("mainForm.Location.X")) {
88 int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
90 int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
92 this.Location = new Point(x, y);
94 StartPosition = FormStartPosition.CenterScreen;
97 Width = Utilities.Config.Get("mainForm.Width", Width);
98 Height = Utilities.Config.Get("mainForm.Height", Height);
100 foreach (TreeColumn column in treeView.Columns)
101 column.Width = Math.Max(20, Math.Min(400,
102 Config.Get("treeView.Columns." + column.Header + ".Width",
105 treeModel = new TreeModel();
106 root = new Node(System.Environment.MachineName);
107 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
109 treeModel.Nodes.Add(root);
110 treeView.Model = treeModel;
112 notifyIcon = new NotifyIcon();
113 notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
114 notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
115 notifyIcon.Text = "Open Hardware Monitor";
116 notifyIcon.DoubleClick += new EventHandler(this.hideShowClick);
118 sensorSystemTray = new SensorSystemTray(computer);
120 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
121 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
124 timer.Enabled = true;
126 plotColorPalette = new Color[13];
127 plotColorPalette[0] = Color.Blue;
128 plotColorPalette[1] = Color.OrangeRed;
129 plotColorPalette[2] = Color.Green;
130 plotColorPalette[3] = Color.LightSeaGreen;
131 plotColorPalette[4] = Color.Goldenrod;
132 plotColorPalette[5] = Color.DarkViolet;
133 plotColorPalette[6] = Color.YellowGreen;
134 plotColorPalette[7] = Color.SaddleBrown;
135 plotColorPalette[8] = Color.RoyalBlue;
136 plotColorPalette[9] = Color.DeepPink;
137 plotColorPalette[10] = Color.MediumSeaGreen;
138 plotColorPalette[11] = Color.Olive;
139 plotColorPalette[12] = Color.Firebrick;
141 hiddenMenuItem.Checked = Config.Get(hiddenMenuItem.Name, false);
142 plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
144 valueMenuItem.Checked = Config.Get(valueMenuItem.Name, true);
145 minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
146 maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
147 limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
149 startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false);
150 minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
151 startupMenuItem.Checked = startupManager.Startup;
152 hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
154 celciusToolStripMenuItem.Checked =
155 UnitManager.TemperatureUnit == TemperatureUnit.Celcius;
156 fahrenheitToolStripMenuItem.Checked = !celciusToolStripMenuItem.Checked;
158 // Hide the system tray and auto startup menu items on Unix
159 int p = (int)System.Environment.OSVersion.Platform;
160 if ((p == 4) || (p == 128)) {
161 minTrayMenuItem.Visible = false;
162 startupMenuItem.Visible = false;
165 if (startMinMenuItem.Checked) {
166 if (!minTrayMenuItem.Checked) {
167 WindowState = FormWindowState.Minimized;
174 // Create a handle, otherwise calling Close() does not fire FormClosed
175 IntPtr handle = Handle;
177 // Make sure the settings are saved when the user logs off
178 Microsoft.Win32.SystemEvents.SessionEnded +=
179 delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
184 private void SubHardwareAdded(IHardware hardware, Node node) {
185 Node hardwareNode = new HardwareNode(hardware);
186 node.Nodes.Add(hardwareNode);
187 foreach (IHardware subHardware in hardware.SubHardware)
188 SubHardwareAdded(subHardware, hardwareNode);
191 private void HardwareAdded(IHardware hardware) {
192 Node hardwareNode = new HardwareNode(hardware);
193 root.Nodes.Add(hardwareNode);
194 foreach (IHardware subHardware in hardware.SubHardware)
195 SubHardwareAdded(subHardware, hardwareNode);
198 private void HardwareRemoved(IHardware hardware) {
199 List<Node> nodesToRemove = new List<Node>();
200 foreach (Node node in root.Nodes) {
201 HardwareNode hardwareNode = node as HardwareNode;
202 if (hardwareNode != null && hardwareNode.Hardware == hardware)
203 nodesToRemove.Add(node);
205 foreach (Node node in nodesToRemove)
206 root.Nodes.Remove(node);
209 private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
210 SensorNode sensorNode = e.Node.Tag as SensorNode;
211 if (sensorNode != null)
212 e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
215 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
216 Node node = e.Node.Tag as Node;
219 if (node.IsVisible) {
220 SensorNode sensorNode = node as SensorNode;
221 if (plotMenuItem.Checked && sensorNode != null &&
222 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
225 e.TextColor = Color.DarkGray;
230 private void UpdatePlotSelection(object sender,
233 List<ISensor> selected = new List<ISensor>();
234 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
236 foreach (TreeNodeAdv node in treeView.AllNodes) {
237 SensorNode sensorNode = node.Tag as SensorNode;
238 if (sensorNode != null &&
239 sensorNode.Sensor.SensorType == SensorType.Temperature) {
240 if (sensorNode.Plot) {
241 colors.Add(sensorNode.Sensor,
242 plotColorPalette[colorIndex % plotColorPalette.Length]);
243 selected.Add(sensorNode.Sensor);
248 sensorPlotColors = colors;
249 plotPanel.SetSensors(selected, colors);
252 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
253 NodeControlValueEventArgs e) {
254 SensorNode node = e.Node.Tag as SensorNode;
255 e.Value = (node != null) &&
256 (node.Sensor.SensorType == SensorType.Temperature) &&
257 plotMenuItem.Checked;
260 private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
264 private void timer_Tick(object sender, EventArgs e) {
265 computer.Accept(updateVisitor);
266 treeView.Invalidate();
267 plotPanel.Invalidate();
268 sensorSystemTray.Redraw();
271 private void SaveConfiguration() {
272 Config.Set(hiddenMenuItem.Name, hiddenMenuItem.Checked);
273 Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
275 Config.Set(valueMenuItem.Name, valueMenuItem.Checked);
276 Config.Set(minMenuItem.Name, minMenuItem.Checked);
277 Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
278 Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
280 Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
281 Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
282 Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
284 if (WindowState != FormWindowState.Minimized) {
285 Config.Set("mainForm.Location.X", Location.X);
286 Config.Set("mainForm.Location.Y", Location.Y);
287 Config.Set("mainForm.Width", Width);
288 Config.Set("mainForm.Height", Height);
291 foreach (TreeColumn column in treeView.Columns)
292 Config.Set("treeView.Columns." + column.Header + ".Width",
298 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
301 timer.Enabled = false;
302 sensorSystemTray.Dispose();
303 notifyIcon.Dispose();
307 private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
308 new AboutBox().ShowDialog();
311 private void plotToolStripMenuItem_CheckedChanged(object sender,
314 splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
315 treeView.Invalidate();
318 private void treeView_Click(object sender, EventArgs e) {
320 MouseEventArgs m = e as MouseEventArgs;
321 if (m == null || m.Button != MouseButtons.Right)
324 NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
325 if (info.Control != null) {
326 SensorNode node = info.Node.Tag as SensorNode;
327 if (node != null && node.Sensor != null) {
329 sensorContextMenuStrip.Items.Clear();
330 if (node.Sensor.Parameters.Length > 0) {
331 ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
332 item.Click += delegate(object obj, EventArgs args) {
333 ShowParameterForm(node.Sensor);
335 sensorContextMenuStrip.Items.Add(item);
337 if (node.IsVisible) {
338 ToolStripMenuItem item = new ToolStripMenuItem("Hide");
339 item.Click += delegate(object obj, EventArgs args) {
340 node.IsVisible = false;
342 sensorContextMenuStrip.Items.Add(item);
344 ToolStripMenuItem item = new ToolStripMenuItem("Unhide");
345 item.Click += delegate(object obj, EventArgs args) {
346 node.IsVisible = true;
348 sensorContextMenuStrip.Items.Add(item);
350 if (sensorSystemTray.Contains(node.Sensor)) {
351 ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
352 item.Click += delegate(object obj, EventArgs args) {
353 sensorSystemTray.Remove(node.Sensor);
355 sensorContextMenuStrip.Items.Add(item);
357 ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
358 item.Click += delegate(object obj, EventArgs args) {
359 sensorSystemTray.Add(node.Sensor, true);
361 sensorContextMenuStrip.Items.Add(item);
363 sensorContextMenuStrip.Show(treeView, m.X, m.Y);
368 private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
369 string report = computer.GetReport();
370 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
371 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
377 private void hddsensorsToolStripMenuItem_CheckedChanged(object sender,
380 computer.HDDEnabled = hddMenuItem.Checked;
381 UpdatePlotSelection(null, null);
384 private void SysTrayHideShow() {
390 protected override void WndProc(ref Message m) {
391 const int WM_SYSCOMMAND = 0x112;
392 const int SC_MINIMIZE = 0xF020;
393 if (minTrayMenuItem.Checked &&
394 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
401 private void hideShowClick(object sender, EventArgs e) {
405 private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
406 ToolStripMenuItem item = sender as ToolStripMenuItem;
410 ISensor sensor = item.Owner.Tag as ISensor;
414 sensorSystemTray.Remove(sensor);
417 private void ShowParameterForm(ISensor sensor) {
418 ParameterForm form = new ParameterForm();
419 form.Parameters = sensor.Parameters;
420 form.captionLabel.Text = sensor.Name;
424 private void treeView_NodeMouseDoubleClick(object sender,
425 TreeNodeAdvMouseEventArgs e) {
426 SensorNode node = e.Node.Tag as SensorNode;
427 if (node != null && node.Sensor != null &&
428 node.Sensor.Parameters.Length > 0) {
429 ShowParameterForm(node.Sensor);
433 private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
434 object sender, EventArgs e)
436 startupManager.Startup = startupMenuItem.Checked;
439 private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
440 notifyIcon.Visible = minTrayMenuItem.Checked;
443 private void hiddenSensorsMenuItem_CheckedChanged(object sender,
445 treeModel.ForceVisible = hiddenMenuItem.Checked;
448 private void valueMenuItem_CheckedChanged(object sender, EventArgs e) {
449 treeView.Columns[1].IsVisible = valueMenuItem.Checked;
452 private void minMenuItem_CheckedChanged(object sender, EventArgs e) {
453 treeView.Columns[2].IsVisible = minMenuItem.Checked;
456 private void maxMenuItem_CheckedChanged(object sender, EventArgs e) {
457 treeView.Columns[3].IsVisible = maxMenuItem.Checked;
460 private void limitMenuItem_CheckedChanged(object sender, EventArgs e) {
461 treeView.Columns[4].IsVisible = limitMenuItem.Checked;
464 private void celciusToolStripMenuItem_Click(object sender, EventArgs e) {
465 celciusToolStripMenuItem.Checked = true;
466 fahrenheitToolStripMenuItem.Checked = false;
467 UnitManager.TemperatureUnit = TemperatureUnit.Celcius;
470 private void fahrenheitToolStripMenuItem_Click(object sender, EventArgs e) {
471 celciusToolStripMenuItem.Checked = false;
472 fahrenheitToolStripMenuItem.Checked = true;
473 UnitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;