Added support for AMD family 11h CPUs.
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.WMI;
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;
77 private WmiProvider wmiProvider;
80 InitializeComponent();
82 this.settings = new PersistentSettings();
83 this.settings.Load(Path.ChangeExtension(
84 Application.ExecutablePath, ".config"));
86 this.unitManager = new UnitManager(settings);
88 // set the DockStyle here, to avoid conflicts with the MainMenu
89 this.splitContainer.Dock = DockStyle.Fill;
91 this.Font = SystemFonts.MessageBoxFont;
92 treeView.Font = SystemFonts.MessageBoxFont;
93 plotPanel.Font = SystemFonts.MessageBoxFont;
95 nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
96 nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
97 nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
98 nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
99 nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
100 nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
101 nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
103 foreach (TreeColumn column in treeView.Columns)
104 column.Width = Math.Max(20, Math.Min(400,
105 settings.GetValue("treeView.Columns." + column.Header + ".Width",
108 treeModel = new TreeModel();
109 root = new Node(System.Environment.MachineName);
110 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
112 treeModel.Nodes.Add(root);
113 treeView.Model = treeModel;
115 this.computer = new Computer(settings);
117 systemTray = new SystemTray(computer, settings);
118 systemTray.HideShowCommand += hideShowClick;
119 systemTray.ExitCommand += exitClick;
121 int p = (int)Environment.OSVersion.Platform;
122 if ((p == 4) || (p == 128)) { // Unix
123 splitContainer.BorderStyle = BorderStyle.None;
124 splitContainer.Border3DStyle = Border3DStyle.Adjust;
125 splitContainer.SplitterWidth = 4;
126 treeView.BorderStyle = BorderStyle.Fixed3D;
127 plotPanel.BorderStyle = BorderStyle.Fixed3D;
128 gadgetMenuItem.Visible = false;
129 minCloseMenuItem.Visible = false;
131 gadget = new SensorGadget(computer, settings, unitManager);
132 gadget.HideShowCommand += hideShowClick;
134 wmiProvider = new WmiProvider(computer);
137 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
138 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
142 timer.Enabled = true;
144 plotColorPalette = new Color[13];
145 plotColorPalette[0] = Color.Blue;
146 plotColorPalette[1] = Color.OrangeRed;
147 plotColorPalette[2] = Color.Green;
148 plotColorPalette[3] = Color.LightSeaGreen;
149 plotColorPalette[4] = Color.Goldenrod;
150 plotColorPalette[5] = Color.DarkViolet;
151 plotColorPalette[6] = Color.YellowGreen;
152 plotColorPalette[7] = Color.SaddleBrown;
153 plotColorPalette[8] = Color.RoyalBlue;
154 plotColorPalette[9] = Color.DeepPink;
155 plotColorPalette[10] = Color.MediumSeaGreen;
156 plotColorPalette[11] = Color.Olive;
157 plotColorPalette[12] = Color.Firebrick;
159 showHiddenSensors = new UserOption("hiddenMenuItem", false,
160 hiddenMenuItem, settings);
161 showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
162 treeModel.ForceVisible = showHiddenSensors.Value;
165 showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
166 showPlot.Changed += delegate(object sender, EventArgs e) {
167 splitContainer.Panel2Collapsed = !showPlot.Value;
168 treeView.Invalidate();
171 showValue = new UserOption("valueMenuItem", true, valueMenuItem,
173 showValue.Changed += delegate(object sender, EventArgs e) {
174 treeView.Columns[1].IsVisible = showValue.Value;
177 showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
178 showMin.Changed += delegate(object sender, EventArgs e) {
179 treeView.Columns[2].IsVisible = showMin.Value;
182 showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
183 showMax.Changed += delegate(object sender, EventArgs e) {
184 treeView.Columns[3].IsVisible = showMax.Value;
187 startMinimized = new UserOption("startMinMenuItem", false,
188 startMinMenuItem, settings);
190 minimizeToTray = new UserOption("minTrayMenuItem", true,
191 minTrayMenuItem, settings);
192 minimizeToTray.Changed += delegate(object sender, EventArgs e) {
193 systemTray.IsMainIconEnabled = minimizeToTray.Value;
196 minimizeOnClose = new UserOption("minCloseMenuItem", false,
197 minCloseMenuItem, settings);
199 autoStart = new UserOption(null, startupManager.Startup,
200 startupMenuItem, settings);
201 autoStart.Changed += delegate(object sender, EventArgs e) {
203 startupManager.Startup = autoStart.Value;
204 } catch (InvalidOperationException) {
205 MessageBox.Show("Updating the auto-startup option failed.", "Error",
206 MessageBoxButtons.OK, MessageBoxIcon.Error);
207 autoStart.Value = startupManager.Startup;
211 readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
213 readHddSensors.Changed += delegate(object sender, EventArgs e) {
214 computer.HDDEnabled = readHddSensors.Value;
215 UpdatePlotSelection(null, null);
218 showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
220 showGadget.Changed += delegate(object sender, EventArgs e) {
222 gadget.Visible = showGadget.Value;
225 celciusMenuItem.Checked =
226 unitManager.TemperatureUnit == TemperatureUnit.Celcius;
227 fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
229 startupMenuItem.Visible = startupManager.IsAvailable;
231 if (startMinMenuItem.Checked) {
232 if (!minTrayMenuItem.Checked) {
233 WindowState = FormWindowState.Minimized;
240 // Create a handle, otherwise calling Close() does not fire FormClosed
241 IntPtr handle = Handle;
243 // Make sure the settings are saved when the user logs off
244 Microsoft.Win32.SystemEvents.SessionEnded += delegate {
249 private void SubHardwareAdded(IHardware hardware, Node node) {
250 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
251 node.Nodes.Add(hardwareNode);
252 foreach (IHardware subHardware in hardware.SubHardware)
253 SubHardwareAdded(subHardware, hardwareNode);
256 private void HardwareAdded(IHardware hardware) {
257 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
258 root.Nodes.Add(hardwareNode);
259 foreach (IHardware subHardware in hardware.SubHardware)
260 SubHardwareAdded(subHardware, hardwareNode);
263 private void HardwareRemoved(IHardware hardware) {
264 List<Node> nodesToRemove = new List<Node>();
265 foreach (Node node in root.Nodes) {
266 HardwareNode hardwareNode = node as HardwareNode;
267 if (hardwareNode != null && hardwareNode.Hardware == hardware)
268 nodesToRemove.Add(node);
270 foreach (Node node in nodesToRemove)
271 root.Nodes.Remove(node);
274 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
275 Node node = e.Node.Tag as Node;
278 if (node.IsVisible) {
279 SensorNode sensorNode = node as SensorNode;
280 if (plotMenuItem.Checked && sensorNode != null &&
281 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
284 e.TextColor = Color.DarkGray;
289 private void UpdatePlotSelection(object sender,
292 List<ISensor> selected = new List<ISensor>();
293 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
295 foreach (TreeNodeAdv node in treeView.AllNodes) {
296 SensorNode sensorNode = node.Tag as SensorNode;
297 if (sensorNode != null &&
298 sensorNode.Sensor.SensorType == SensorType.Temperature) {
299 if (sensorNode.Plot) {
300 colors.Add(sensorNode.Sensor,
301 plotColorPalette[colorIndex % plotColorPalette.Length]);
302 selected.Add(sensorNode.Sensor);
307 sensorPlotColors = colors;
308 plotPanel.SetSensors(selected, colors);
311 private void nodeTextBoxText_EditorShowing(object sender,
314 e.Cancel = !(treeView.CurrentNode != null &&
315 treeView.CurrentNode.Tag is SensorNode);
318 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
319 NodeControlValueEventArgs e) {
320 SensorNode node = e.Node.Tag as SensorNode;
321 e.Value = (node != null) &&
322 (node.Sensor.SensorType == SensorType.Temperature) &&
323 plotMenuItem.Checked;
326 private void exitClick(object sender, EventArgs e) {
330 private void timer_Tick(object sender, EventArgs e) {
331 computer.Accept(updateVisitor);
332 treeView.Invalidate();
333 plotPanel.Invalidate();
338 if (wmiProvider != null)
339 wmiProvider.Update();
342 private void SaveConfiguration() {
343 foreach (TreeColumn column in treeView.Columns)
344 settings.SetValue("treeView.Columns." + column.Header + ".Width",
347 string fileName = Path.ChangeExtension(
348 System.Windows.Forms.Application.ExecutablePath, ".config");
350 settings.Save(fileName);
351 } catch (UnauthorizedAccessException) {
352 MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
353 "The current seetings could not be saved.",
354 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
358 private void MainForm_Load(object sender, EventArgs e) {
359 Rectangle newBounds = new Rectangle {
360 X = settings.GetValue("mainForm.Location.X", Location.X),
361 Y = settings.GetValue("mainForm.Location.Y", Location.Y),
362 Width = settings.GetValue("mainForm.Width", 470),
363 Height = settings.GetValue("mainForm.Height", 640)
366 Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
367 int.MinValue, int.MinValue);
369 foreach (Screen screen in Screen.AllScreens)
370 fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
372 Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
373 if (intersection.Width < 20 || intersection.Height < 20 ||
374 !settings.Contains("mainForm.Location.X")
376 newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
379 newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
380 (newBounds.Height / 2);
383 this.Bounds = newBounds;
386 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
390 timer.Enabled = false;
391 systemTray.Dispose();
395 private void aboutMenuItem_Click(object sender, EventArgs e) {
396 new AboutBox().ShowDialog();
399 private void treeView_Click(object sender, EventArgs e) {
401 MouseEventArgs m = e as MouseEventArgs;
402 if (m == null || m.Button != MouseButtons.Right)
405 NodeControlInfo info = treeView.GetNodeControlInfoAt(
408 treeView.SelectedNode = info.Node;
409 if (info.Node != null) {
410 SensorNode node = info.Node.Tag as SensorNode;
411 if (node != null && node.Sensor != null) {
412 sensorContextMenu.MenuItems.Clear();
413 if (node.Sensor.Parameters.Length > 0) {
414 MenuItem item = new MenuItem("Parameters...");
415 item.Click += delegate(object obj, EventArgs args) {
416 ShowParameterForm(node.Sensor);
418 sensorContextMenu.MenuItems.Add(item);
420 if (nodeTextBoxText.EditEnabled) {
421 MenuItem item = new MenuItem("Rename");
422 item.Click += delegate(object obj, EventArgs args) {
423 nodeTextBoxText.BeginEdit();
425 sensorContextMenu.MenuItems.Add(item);
427 if (node.IsVisible) {
428 MenuItem item = new MenuItem("Hide");
429 item.Click += delegate(object obj, EventArgs args) {
430 node.IsVisible = false;
432 sensorContextMenu.MenuItems.Add(item);
434 MenuItem item = new MenuItem("Unhide");
435 item.Click += delegate(object obj, EventArgs args) {
436 node.IsVisible = true;
438 sensorContextMenu.MenuItems.Add(item);
440 sensorContextMenu.MenuItems.Add(new MenuItem("-"));
442 MenuItem item = new MenuItem("Show in Tray");
443 item.Checked = systemTray.Contains(node.Sensor);
444 item.Click += delegate(object obj, EventArgs args) {
446 systemTray.Remove(node.Sensor);
448 systemTray.Add(node.Sensor, true);
450 sensorContextMenu.MenuItems.Add(item);
452 if (gadget != null) {
453 MenuItem item = new MenuItem("Show in Gadget");
454 item.Checked = gadget.Contains(node.Sensor);
455 item.Click += delegate(object obj, EventArgs args) {
457 gadget.Remove(node.Sensor);
459 gadget.Add(node.Sensor);
462 sensorContextMenu.MenuItems.Add(item);
464 if (node.Sensor.Control != null) {
465 sensorContextMenu.MenuItems.Add(new MenuItem("-"));
466 IControl control = node.Sensor.Control;
467 MenuItem controlItem = new MenuItem("Control");
468 MenuItem defaultItem = new MenuItem("Default");
469 defaultItem.Checked = control.ControlMode == ControlMode.Default;
470 controlItem.MenuItems.Add(defaultItem);
471 defaultItem.Click += delegate(object obj, EventArgs args) {
472 control.SetDefault();
474 MenuItem manualItem = new MenuItem("Manual");
475 controlItem.MenuItems.Add(manualItem);
476 manualItem.Checked = control.ControlMode == ControlMode.Software;
477 for (int i = 0; i <= 100; i += 5) {
478 if (i <= control.MaxSoftwareValue &&
479 i >= control.MinSoftwareValue)
481 MenuItem item = new MenuItem(i + " %");
482 manualItem.MenuItems.Add(item);
483 item.Checked = control.ControlMode == ControlMode.Software &&
484 Math.Round(control.SoftwareValue) == i;
485 int softwareValue = i;
486 item.Click += delegate(object obj, EventArgs args) {
487 control.SetSoftware(softwareValue);
491 sensorContextMenu.MenuItems.Add(controlItem);
494 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
499 private void saveReportMenuItem_Click(object sender, EventArgs e) {
500 string report = computer.GetReport();
501 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
502 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
508 private void SysTrayHideShow() {
514 protected override void WndProc(ref Message m) {
515 const int WM_SYSCOMMAND = 0x112;
516 const int SC_MINIMIZE = 0xF020;
517 const int SC_CLOSE = 0xF060;
519 if (minimizeToTray.Value &&
520 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
522 } else if(minimizeOnClose.Value &&
523 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) {
525 * Apparently the user wants to minimize rather than close
526 * Now we still need to check if we're going to the tray or not
528 * Note: the correct way to do this would be to send out SC_MINIMIZE,
529 * but since the code here is so simple,
530 * that would just be a waste of time.
532 if (minimizeToTray.Value)
535 WindowState = FormWindowState.Minimized;
541 private void hideShowClick(object sender, EventArgs e) {
545 private void ShowParameterForm(ISensor sensor) {
546 ParameterForm form = new ParameterForm();
547 form.Parameters = sensor.Parameters;
548 form.captionLabel.Text = sensor.Name;
552 private void treeView_NodeMouseDoubleClick(object sender,
553 TreeNodeAdvMouseEventArgs e) {
554 SensorNode node = e.Node.Tag as SensorNode;
555 if (node != null && node.Sensor != null &&
556 node.Sensor.Parameters.Length > 0) {
557 ShowParameterForm(node.Sensor);
561 private void celciusMenuItem_Click(object sender, EventArgs e) {
562 celciusMenuItem.Checked = true;
563 fahrenheitMenuItem.Checked = false;
564 unitManager.TemperatureUnit = TemperatureUnit.Celcius;
567 private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
568 celciusMenuItem.Checked = false;
569 fahrenheitMenuItem.Checked = true;
570 unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
573 private void sumbitReportMenuItem_Click(object sender, EventArgs e)
575 ReportForm form = new ReportForm();
576 form.Report = computer.GetReport();
580 private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
581 computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
587 private void MainForm_MoveOrResize(object sender, EventArgs e) {
588 if (WindowState != FormWindowState.Minimized) {
589 settings.SetValue("mainForm.Location.X", Bounds.X);
590 settings.SetValue("mainForm.Location.Y", Bounds.Y);
591 settings.SetValue("mainForm.Width", Bounds.Width);
592 settings.SetValue("mainForm.Height", Bounds.Height);