Added license to the WMI stuff and refactored a few things a little.
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.
22 Contributor(s): Paul Werelds
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;
43 using System.Windows.Forms;
44 using Aga.Controls.Tree;
45 using Aga.Controls.Tree.NodeControls;
46 using OpenHardwareMonitor.Hardware;
47 using OpenHardwareMonitor.WMIProvider;
49 namespace OpenHardwareMonitor.GUI {
50 public partial class MainForm : Form {
52 private PersistentSettings settings;
53 private UnitManager unitManager;
54 private Computer computer;
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;
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 private UserOption enableWmiProvider;
78 private WmiProvider wmiProvider;
81 InitializeComponent();
83 this.settings = new PersistentSettings();
84 this.settings.Load(Path.ChangeExtension(
85 Application.ExecutablePath, ".config"));
87 this.unitManager = new UnitManager(settings);
89 // set the DockStyle here, to avoid conflicts with the MainMenu
90 this.splitContainer.Dock = DockStyle.Fill;
92 this.Font = SystemFonts.MessageBoxFont;
93 treeView.Font = SystemFonts.MessageBoxFont;
94 plotPanel.Font = SystemFonts.MessageBoxFont;
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;
104 foreach (TreeColumn column in treeView.Columns)
105 column.Width = Math.Max(20, Math.Min(400,
106 settings.GetValue("treeView.Columns." + column.Header + ".Width",
109 treeModel = new TreeModel();
110 root = new Node(System.Environment.MachineName);
111 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
113 treeModel.Nodes.Add(root);
114 treeView.Model = treeModel;
116 this.computer = new Computer(settings);
118 systemTray = new SystemTray(computer, settings);
119 systemTray.HideShowCommand += hideShowClick;
120 systemTray.ExitCommand += exitClick;
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;
132 gadget = new SensorGadget(computer, settings, unitManager);
135 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
136 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
138 if (settings.GetValue("enableWmiProvider", false))
139 wmiProvider = new WmiProvider(computer);
143 timer.Enabled = true;
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;
160 showHiddenSensors = new UserOption("hiddenMenuItem", false,
161 hiddenMenuItem, settings);
162 showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
163 treeModel.ForceVisible = showHiddenSensors.Value;
166 showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
167 showPlot.Changed += delegate(object sender, EventArgs e) {
168 splitContainer.Panel2Collapsed = !showPlot.Value;
169 treeView.Invalidate();
172 showValue = new UserOption("valueMenuItem", true, valueMenuItem,
174 showValue.Changed += delegate(object sender, EventArgs e) {
175 treeView.Columns[1].IsVisible = showValue.Value;
178 showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
179 showMin.Changed += delegate(object sender, EventArgs e) {
180 treeView.Columns[2].IsVisible = showMin.Value;
183 showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
184 showMax.Changed += delegate(object sender, EventArgs e) {
185 treeView.Columns[3].IsVisible = showMax.Value;
188 startMinimized = new UserOption("startMinMenuItem", false,
189 startMinMenuItem, settings);
191 minimizeToTray = new UserOption("minTrayMenuItem", true,
192 minTrayMenuItem, settings);
193 minimizeToTray.Changed += delegate(object sender, EventArgs e) {
194 systemTray.IsMainIconEnabled = minimizeToTray.Value;
197 minimizeOnClose = new UserOption("minCloseMenuItem", false,
198 minCloseMenuItem, settings);
200 autoStart = new UserOption(null, startupManager.Startup,
201 startupMenuItem, settings);
202 autoStart.Changed += delegate(object sender, EventArgs e) {
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;
212 readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
214 readHddSensors.Changed += delegate(object sender, EventArgs e) {
215 computer.HDDEnabled = readHddSensors.Value;
216 UpdatePlotSelection(null, null);
219 showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
221 showGadget.Changed += delegate(object sender, EventArgs e) {
223 gadget.Visible = showGadget.Value;
226 enableWmiProvider = new UserOption("enableWmiProvider", false,
227 wmiMenuItem, settings);
228 enableWmiProvider.Changed += delegate {
229 if (enableWmiProvider.Value && wmiProvider == null)
230 wmiProvider = new WmiProvider(computer);
231 else if (!enableWmiProvider.Value && wmiProvider != null) {
232 wmiProvider.Dispose();
237 celciusMenuItem.Checked =
238 unitManager.TemperatureUnit == TemperatureUnit.Celcius;
239 fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
241 startupMenuItem.Visible = startupManager.IsAvailable;
243 if (startMinMenuItem.Checked) {
244 if (!minTrayMenuItem.Checked) {
245 WindowState = FormWindowState.Minimized;
252 // Create a handle, otherwise calling Close() does not fire FormClosed
253 IntPtr handle = Handle;
255 // Make sure the settings are saved when the user logs off
256 Microsoft.Win32.SystemEvents.SessionEnded += delegate {
261 private void SubHardwareAdded(IHardware hardware, Node node) {
262 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
263 node.Nodes.Add(hardwareNode);
264 foreach (IHardware subHardware in hardware.SubHardware)
265 SubHardwareAdded(subHardware, hardwareNode);
268 private void HardwareAdded(IHardware hardware) {
269 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
270 root.Nodes.Add(hardwareNode);
271 foreach (IHardware subHardware in hardware.SubHardware)
272 SubHardwareAdded(subHardware, hardwareNode);
275 private void HardwareRemoved(IHardware hardware) {
276 List<Node> nodesToRemove = new List<Node>();
277 foreach (Node node in root.Nodes) {
278 HardwareNode hardwareNode = node as HardwareNode;
279 if (hardwareNode != null && hardwareNode.Hardware == hardware)
280 nodesToRemove.Add(node);
282 foreach (Node node in nodesToRemove)
283 root.Nodes.Remove(node);
286 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
287 Node node = e.Node.Tag as Node;
290 if (node.IsVisible) {
291 SensorNode sensorNode = node as SensorNode;
292 if (plotMenuItem.Checked && sensorNode != null &&
293 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
296 e.TextColor = Color.DarkGray;
301 private void UpdatePlotSelection(object sender,
304 List<ISensor> selected = new List<ISensor>();
305 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
307 foreach (TreeNodeAdv node in treeView.AllNodes) {
308 SensorNode sensorNode = node.Tag as SensorNode;
309 if (sensorNode != null &&
310 sensorNode.Sensor.SensorType == SensorType.Temperature) {
311 if (sensorNode.Plot) {
312 colors.Add(sensorNode.Sensor,
313 plotColorPalette[colorIndex % plotColorPalette.Length]);
314 selected.Add(sensorNode.Sensor);
319 sensorPlotColors = colors;
320 plotPanel.SetSensors(selected, colors);
323 private void nodeTextBoxText_EditorShowing(object sender,
326 e.Cancel = !(treeView.CurrentNode != null &&
327 treeView.CurrentNode.Tag is SensorNode);
330 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
331 NodeControlValueEventArgs e) {
332 SensorNode node = e.Node.Tag as SensorNode;
333 e.Value = (node != null) &&
334 (node.Sensor.SensorType == SensorType.Temperature) &&
335 plotMenuItem.Checked;
338 private void exitClick(object sender, EventArgs e) {
342 private void timer_Tick(object sender, EventArgs e) {
343 computer.Accept(updateVisitor);
344 treeView.Invalidate();
345 plotPanel.Invalidate();
350 if (wmiProvider != null)
351 wmiProvider.Update();
354 private void SaveConfiguration() {
355 if (WindowState != FormWindowState.Minimized) {
356 settings.SetValue("mainForm.Location.X", Bounds.X);
357 settings.SetValue("mainForm.Location.Y", Bounds.Y);
358 settings.SetValue("mainForm.Width", Bounds.Width);
359 settings.SetValue("mainForm.Height", Bounds.Height);
362 foreach (TreeColumn column in treeView.Columns)
363 settings.SetValue("treeView.Columns." + column.Header + ".Width",
366 string fileName = Path.ChangeExtension(
367 System.Windows.Forms.Application.ExecutablePath, ".config");
369 settings.Save(fileName);
370 } catch (UnauthorizedAccessException) {
371 MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
372 "The current seetings could not be saved.",
373 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
377 private void MainForm_Load(object sender, EventArgs e) {
378 Rectangle newBounds = new Rectangle {
379 X = settings.GetValue("mainForm.Location.X", Location.X),
380 Y = settings.GetValue("mainForm.Location.Y", Location.Y),
381 Width = settings.GetValue("mainForm.Width", 470),
382 Height = settings.GetValue("mainForm.Height", 640)
385 Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
386 int.MinValue, int.MinValue);
388 foreach (Screen screen in Screen.AllScreens)
389 fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
391 Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
392 if (intersection.Width < 20 || intersection.Height < 20 ||
393 !settings.Contains("mainForm.Location.X")
395 newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
398 newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
399 (newBounds.Height / 2);
402 this.Bounds = newBounds;
405 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
409 timer.Enabled = false;
410 systemTray.Dispose();
414 private void aboutMenuItem_Click(object sender, EventArgs e) {
415 new AboutBox().ShowDialog();
418 private void treeView_Click(object sender, EventArgs e) {
420 MouseEventArgs m = e as MouseEventArgs;
421 if (m == null || m.Button != MouseButtons.Right)
424 NodeControlInfo info = treeView.GetNodeControlInfoAt(
427 treeView.SelectedNode = info.Node;
428 if (info.Node != null) {
429 SensorNode node = info.Node.Tag as SensorNode;
430 if (node != null && node.Sensor != null) {
431 sensorContextMenu.MenuItems.Clear();
432 if (node.Sensor.Parameters.Length > 0) {
433 MenuItem item = new MenuItem("Parameters...");
434 item.Click += delegate(object obj, EventArgs args) {
435 ShowParameterForm(node.Sensor);
437 sensorContextMenu.MenuItems.Add(item);
439 if (nodeTextBoxText.EditEnabled) {
440 MenuItem item = new MenuItem("Rename");
441 item.Click += delegate(object obj, EventArgs args) {
442 nodeTextBoxText.BeginEdit();
444 sensorContextMenu.MenuItems.Add(item);
446 if (node.IsVisible) {
447 MenuItem item = new MenuItem("Hide");
448 item.Click += delegate(object obj, EventArgs args) {
449 node.IsVisible = false;
451 sensorContextMenu.MenuItems.Add(item);
453 MenuItem item = new MenuItem("Unhide");
454 item.Click += delegate(object obj, EventArgs args) {
455 node.IsVisible = true;
457 sensorContextMenu.MenuItems.Add(item);
459 sensorContextMenu.MenuItems.Add(new MenuItem("-"));
461 MenuItem item = new MenuItem("Show in Tray");
462 item.Checked = systemTray.Contains(node.Sensor);
463 item.Click += delegate(object obj, EventArgs args) {
465 systemTray.Remove(node.Sensor);
467 systemTray.Add(node.Sensor, true);
469 sensorContextMenu.MenuItems.Add(item);
471 if (gadget != null) {
472 MenuItem item = new MenuItem("Show in Gadget");
473 item.Checked = gadget.Contains(node.Sensor);
474 item.Click += delegate(object obj, EventArgs args) {
476 gadget.Remove(node.Sensor);
478 gadget.Add(node.Sensor);
481 sensorContextMenu.MenuItems.Add(item);
484 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
489 private void saveReportMenuItem_Click(object sender, EventArgs e) {
490 string report = computer.GetReport();
491 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
492 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
498 private void SysTrayHideShow() {
504 protected override void WndProc(ref Message m) {
505 const int WM_SYSCOMMAND = 0x112;
506 const int SC_MINIMIZE = 0xF020;
507 const int SC_CLOSE = 0xF060;
509 if (minimizeToTray.Value &&
510 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
512 } else if(minimizeOnClose.Value &&
513 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) {
515 * Apparently the user wants to minimize rather than close
516 * Now we still need to check if we're going to the tray or not
518 * Note: the correct way to do this would be to send out SC_MINIMIZE,
519 * but since the code here is so simple,
520 * that would just be a waste of time.
522 if (minimizeToTray.Value)
525 WindowState = FormWindowState.Minimized;
531 private void hideShowClick(object sender, EventArgs e) {
535 private void ShowParameterForm(ISensor sensor) {
536 ParameterForm form = new ParameterForm();
537 form.Parameters = sensor.Parameters;
538 form.captionLabel.Text = sensor.Name;
542 private void treeView_NodeMouseDoubleClick(object sender,
543 TreeNodeAdvMouseEventArgs e) {
544 SensorNode node = e.Node.Tag as SensorNode;
545 if (node != null && node.Sensor != null &&
546 node.Sensor.Parameters.Length > 0) {
547 ShowParameterForm(node.Sensor);
551 private void celciusMenuItem_Click(object sender, EventArgs e) {
552 celciusMenuItem.Checked = true;
553 fahrenheitMenuItem.Checked = false;
554 unitManager.TemperatureUnit = TemperatureUnit.Celcius;
557 private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
558 celciusMenuItem.Checked = false;
559 fahrenheitMenuItem.Checked = true;
560 unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
563 private void sumbitReportMenuItem_Click(object sender, EventArgs e)
565 ReportForm form = new ReportForm();
566 form.Report = computer.GetReport();
570 private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
571 computer.Accept(new SensorVisitor(delegate(ISensor sensor) {