Added a workaround for the "You must keep the stream open for the lifetime of the Image." problem of the Image.FromStream method. This also reduced the overall memory usage (private working set).
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;
178 private void SubHardwareAdded(IHardware hardware, Node node) {
179 Node hardwareNode = new HardwareNode(hardware);
180 node.Nodes.Add(hardwareNode);
181 foreach (IHardware subHardware in hardware.SubHardware)
182 SubHardwareAdded(subHardware, hardwareNode);
185 private void HardwareAdded(IHardware hardware) {
186 Node hardwareNode = new HardwareNode(hardware);
187 root.Nodes.Add(hardwareNode);
188 foreach (IHardware subHardware in hardware.SubHardware)
189 SubHardwareAdded(subHardware, hardwareNode);
192 private void HardwareRemoved(IHardware hardware) {
193 List<Node> nodesToRemove = new List<Node>();
194 foreach (Node node in root.Nodes) {
195 HardwareNode hardwareNode = node as HardwareNode;
196 if (hardwareNode != null && hardwareNode.Hardware == hardware)
197 nodesToRemove.Add(node);
199 foreach (Node node in nodesToRemove)
200 root.Nodes.Remove(node);
203 private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
204 SensorNode sensorNode = e.Node.Tag as SensorNode;
205 if (sensorNode != null)
206 e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
209 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
210 Node node = e.Node.Tag as Node;
213 if (node.IsVisible) {
214 SensorNode sensorNode = node as SensorNode;
215 if (plotMenuItem.Checked && sensorNode != null &&
216 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
219 e.TextColor = Color.DarkGray;
224 private void UpdatePlotSelection(object sender,
227 List<ISensor> selected = new List<ISensor>();
228 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
230 foreach (TreeNodeAdv node in treeView.AllNodes) {
231 SensorNode sensorNode = node.Tag as SensorNode;
232 if (sensorNode != null &&
233 sensorNode.Sensor.SensorType == SensorType.Temperature) {
234 if (sensorNode.Plot) {
235 colors.Add(sensorNode.Sensor,
236 plotColorPalette[colorIndex % plotColorPalette.Length]);
237 selected.Add(sensorNode.Sensor);
242 sensorPlotColors = colors;
243 plotPanel.SetSensors(selected, colors);
246 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
247 NodeControlValueEventArgs e) {
248 SensorNode node = e.Node.Tag as SensorNode;
249 e.Value = (node != null) &&
250 (node.Sensor.SensorType == SensorType.Temperature) &&
251 plotMenuItem.Checked;
254 private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
258 private void timer_Tick(object sender, EventArgs e) {
259 computer.Accept(updateVisitor);
260 treeView.Invalidate();
261 plotPanel.Invalidate();
262 sensorSystemTray.Redraw();
265 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
267 Config.Set(hiddenMenuItem.Name, hiddenMenuItem.Checked);
268 Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
270 Config.Set(valueMenuItem.Name, valueMenuItem.Checked);
271 Config.Set(minMenuItem.Name, minMenuItem.Checked);
272 Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
273 Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
275 Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
276 Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
277 Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
279 if (WindowState != FormWindowState.Minimized) {
280 Config.Set("mainForm.Location.X", Location.X);
281 Config.Set("mainForm.Location.Y", Location.Y);
282 Config.Set("mainForm.Width", Width);
283 Config.Set("mainForm.Height", Height);
286 foreach (TreeColumn column in treeView.Columns)
287 Config.Set("treeView.Columns." + column.Header + ".Width",
290 timer.Enabled = false;
292 sensorSystemTray.Dispose();
293 notifyIcon.Dispose();
297 private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
298 new AboutBox().ShowDialog();
301 private void plotToolStripMenuItem_CheckedChanged(object sender,
304 splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
305 treeView.Invalidate();
308 private void treeView_Click(object sender, EventArgs e) {
310 MouseEventArgs m = e as MouseEventArgs;
311 if (m == null || m.Button != MouseButtons.Right)
314 NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
315 if (info.Control != null) {
316 SensorNode node = info.Node.Tag as SensorNode;
317 if (node != null && node.Sensor != null) {
319 sensorContextMenuStrip.Items.Clear();
320 if (node.Sensor.Parameters.Length > 0) {
321 ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
322 item.Click += delegate(object obj, EventArgs args) {
323 ShowParameterForm(node.Sensor);
325 sensorContextMenuStrip.Items.Add(item);
327 if (node.IsVisible) {
328 ToolStripMenuItem item = new ToolStripMenuItem("Hide");
329 item.Click += delegate(object obj, EventArgs args) {
330 node.IsVisible = false;
332 sensorContextMenuStrip.Items.Add(item);
334 ToolStripMenuItem item = new ToolStripMenuItem("Unhide");
335 item.Click += delegate(object obj, EventArgs args) {
336 node.IsVisible = true;
338 sensorContextMenuStrip.Items.Add(item);
340 if (sensorSystemTray.Contains(node.Sensor)) {
341 ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
342 item.Click += delegate(object obj, EventArgs args) {
343 sensorSystemTray.Remove(node.Sensor);
345 sensorContextMenuStrip.Items.Add(item);
347 ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
348 item.Click += delegate(object obj, EventArgs args) {
349 sensorSystemTray.Add(node.Sensor, true);
351 sensorContextMenuStrip.Items.Add(item);
353 sensorContextMenuStrip.Show(treeView, m.X, m.Y);
358 private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
359 string report = computer.GetReport();
360 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
361 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
367 private void hddsensorsToolStripMenuItem_CheckedChanged(object sender,
370 computer.HDDEnabled = hddMenuItem.Checked;
371 UpdatePlotSelection(null, null);
374 private void SysTrayHideShow() {
380 protected override void WndProc(ref Message m) {
381 const int WM_SYSCOMMAND = 0x112;
382 const int SC_MINIMIZE = 0xF020;
383 if (minTrayMenuItem.Checked &&
384 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
391 private void hideShowClick(object sender, EventArgs e) {
395 private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
396 ToolStripMenuItem item = sender as ToolStripMenuItem;
400 ISensor sensor = item.Owner.Tag as ISensor;
404 sensorSystemTray.Remove(sensor);
407 private void ShowParameterForm(ISensor sensor) {
408 ParameterForm form = new ParameterForm();
409 form.Parameters = sensor.Parameters;
410 form.captionLabel.Text = sensor.Name;
414 private void treeView_NodeMouseDoubleClick(object sender,
415 TreeNodeAdvMouseEventArgs e) {
416 SensorNode node = e.Node.Tag as SensorNode;
417 if (node != null && node.Sensor != null &&
418 node.Sensor.Parameters.Length > 0) {
419 ShowParameterForm(node.Sensor);
423 private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
424 object sender, EventArgs e)
426 startupManager.Startup = startupMenuItem.Checked;
429 private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
430 notifyIcon.Visible = minTrayMenuItem.Checked;
433 private void hiddenSensorsMenuItem_CheckedChanged(object sender,
435 treeModel.ForceVisible = hiddenMenuItem.Checked;
438 private void valueMenuItem_CheckedChanged(object sender, EventArgs e) {
439 treeView.Columns[1].IsVisible = valueMenuItem.Checked;
442 private void minMenuItem_CheckedChanged(object sender, EventArgs e) {
443 treeView.Columns[2].IsVisible = minMenuItem.Checked;
446 private void maxMenuItem_CheckedChanged(object sender, EventArgs e) {
447 treeView.Columns[3].IsVisible = maxMenuItem.Checked;
450 private void limitMenuItem_CheckedChanged(object sender, EventArgs e) {
451 treeView.Columns[4].IsVisible = limitMenuItem.Checked;
454 private void celciusToolStripMenuItem_Click(object sender, EventArgs e) {
455 celciusToolStripMenuItem.Checked = true;
456 fahrenheitToolStripMenuItem.Checked = false;
457 UnitManager.TemperatureUnit = TemperatureUnit.Celcius;
460 private void fahrenheitToolStripMenuItem_Click(object sender, EventArgs e) {
461 celciusToolStripMenuItem.Checked = false;
462 fahrenheitToolStripMenuItem.Checked = true;
463 UnitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;