Improved the moving and resizing of the gadget on multi-monitor systems. Fixed one problem where the underlying gadget window size would be reduced unrequested. Fine tuned the progress bar size in the gadget.
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 wmiProvider = new WmiProvider(computer);
135 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
136 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
140 timer.Enabled = true;
142 plotColorPalette = new Color[13];
143 plotColorPalette[0] = Color.Blue;
144 plotColorPalette[1] = Color.OrangeRed;
145 plotColorPalette[2] = Color.Green;
146 plotColorPalette[3] = Color.LightSeaGreen;
147 plotColorPalette[4] = Color.Goldenrod;
148 plotColorPalette[5] = Color.DarkViolet;
149 plotColorPalette[6] = Color.YellowGreen;
150 plotColorPalette[7] = Color.SaddleBrown;
151 plotColorPalette[8] = Color.RoyalBlue;
152 plotColorPalette[9] = Color.DeepPink;
153 plotColorPalette[10] = Color.MediumSeaGreen;
154 plotColorPalette[11] = Color.Olive;
155 plotColorPalette[12] = Color.Firebrick;
157 showHiddenSensors = new UserOption("hiddenMenuItem", false,
158 hiddenMenuItem, settings);
159 showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
160 treeModel.ForceVisible = showHiddenSensors.Value;
163 showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
164 showPlot.Changed += delegate(object sender, EventArgs e) {
165 splitContainer.Panel2Collapsed = !showPlot.Value;
166 treeView.Invalidate();
169 showValue = new UserOption("valueMenuItem", true, valueMenuItem,
171 showValue.Changed += delegate(object sender, EventArgs e) {
172 treeView.Columns[1].IsVisible = showValue.Value;
175 showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
176 showMin.Changed += delegate(object sender, EventArgs e) {
177 treeView.Columns[2].IsVisible = showMin.Value;
180 showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
181 showMax.Changed += delegate(object sender, EventArgs e) {
182 treeView.Columns[3].IsVisible = showMax.Value;
185 startMinimized = new UserOption("startMinMenuItem", false,
186 startMinMenuItem, settings);
188 minimizeToTray = new UserOption("minTrayMenuItem", true,
189 minTrayMenuItem, settings);
190 minimizeToTray.Changed += delegate(object sender, EventArgs e) {
191 systemTray.IsMainIconEnabled = minimizeToTray.Value;
194 minimizeOnClose = new UserOption("minCloseMenuItem", false,
195 minCloseMenuItem, settings);
197 autoStart = new UserOption(null, startupManager.Startup,
198 startupMenuItem, settings);
199 autoStart.Changed += delegate(object sender, EventArgs e) {
201 startupManager.Startup = autoStart.Value;
202 } catch (InvalidOperationException) {
203 MessageBox.Show("Updating the auto-startup option failed.", "Error",
204 MessageBoxButtons.OK, MessageBoxIcon.Error);
205 autoStart.Value = startupManager.Startup;
209 readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
211 readHddSensors.Changed += delegate(object sender, EventArgs e) {
212 computer.HDDEnabled = readHddSensors.Value;
213 UpdatePlotSelection(null, null);
216 showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
218 showGadget.Changed += delegate(object sender, EventArgs e) {
220 gadget.Visible = showGadget.Value;
223 celciusMenuItem.Checked =
224 unitManager.TemperatureUnit == TemperatureUnit.Celcius;
225 fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
227 startupMenuItem.Visible = startupManager.IsAvailable;
229 if (startMinMenuItem.Checked) {
230 if (!minTrayMenuItem.Checked) {
231 WindowState = FormWindowState.Minimized;
238 // Create a handle, otherwise calling Close() does not fire FormClosed
239 IntPtr handle = Handle;
241 // Make sure the settings are saved when the user logs off
242 Microsoft.Win32.SystemEvents.SessionEnded += delegate {
247 private void SubHardwareAdded(IHardware hardware, Node node) {
248 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
249 node.Nodes.Add(hardwareNode);
250 foreach (IHardware subHardware in hardware.SubHardware)
251 SubHardwareAdded(subHardware, hardwareNode);
254 private void HardwareAdded(IHardware hardware) {
255 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
256 root.Nodes.Add(hardwareNode);
257 foreach (IHardware subHardware in hardware.SubHardware)
258 SubHardwareAdded(subHardware, hardwareNode);
261 private void HardwareRemoved(IHardware hardware) {
262 List<Node> nodesToRemove = new List<Node>();
263 foreach (Node node in root.Nodes) {
264 HardwareNode hardwareNode = node as HardwareNode;
265 if (hardwareNode != null && hardwareNode.Hardware == hardware)
266 nodesToRemove.Add(node);
268 foreach (Node node in nodesToRemove)
269 root.Nodes.Remove(node);
272 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
273 Node node = e.Node.Tag as Node;
276 if (node.IsVisible) {
277 SensorNode sensorNode = node as SensorNode;
278 if (plotMenuItem.Checked && sensorNode != null &&
279 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
282 e.TextColor = Color.DarkGray;
287 private void UpdatePlotSelection(object sender,
290 List<ISensor> selected = new List<ISensor>();
291 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
293 foreach (TreeNodeAdv node in treeView.AllNodes) {
294 SensorNode sensorNode = node.Tag as SensorNode;
295 if (sensorNode != null &&
296 sensorNode.Sensor.SensorType == SensorType.Temperature) {
297 if (sensorNode.Plot) {
298 colors.Add(sensorNode.Sensor,
299 plotColorPalette[colorIndex % plotColorPalette.Length]);
300 selected.Add(sensorNode.Sensor);
305 sensorPlotColors = colors;
306 plotPanel.SetSensors(selected, colors);
309 private void nodeTextBoxText_EditorShowing(object sender,
312 e.Cancel = !(treeView.CurrentNode != null &&
313 treeView.CurrentNode.Tag is SensorNode);
316 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
317 NodeControlValueEventArgs e) {
318 SensorNode node = e.Node.Tag as SensorNode;
319 e.Value = (node != null) &&
320 (node.Sensor.SensorType == SensorType.Temperature) &&
321 plotMenuItem.Checked;
324 private void exitClick(object sender, EventArgs e) {
328 private void timer_Tick(object sender, EventArgs e) {
329 computer.Accept(updateVisitor);
330 treeView.Invalidate();
331 plotPanel.Invalidate();
336 if (wmiProvider != null)
337 wmiProvider.Update();
340 private void SaveConfiguration() {
341 foreach (TreeColumn column in treeView.Columns)
342 settings.SetValue("treeView.Columns." + column.Header + ".Width",
345 string fileName = Path.ChangeExtension(
346 System.Windows.Forms.Application.ExecutablePath, ".config");
348 settings.Save(fileName);
349 } catch (UnauthorizedAccessException) {
350 MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
351 "The current seetings could not be saved.",
352 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
356 private void MainForm_Load(object sender, EventArgs e) {
357 Rectangle newBounds = new Rectangle {
358 X = settings.GetValue("mainForm.Location.X", Location.X),
359 Y = settings.GetValue("mainForm.Location.Y", Location.Y),
360 Width = settings.GetValue("mainForm.Width", 470),
361 Height = settings.GetValue("mainForm.Height", 640)
364 Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
365 int.MinValue, int.MinValue);
367 foreach (Screen screen in Screen.AllScreens)
368 fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
370 Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
371 if (intersection.Width < 20 || intersection.Height < 20 ||
372 !settings.Contains("mainForm.Location.X")
374 newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
377 newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
378 (newBounds.Height / 2);
381 this.Bounds = newBounds;
384 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
388 timer.Enabled = false;
389 systemTray.Dispose();
393 private void aboutMenuItem_Click(object sender, EventArgs e) {
394 new AboutBox().ShowDialog();
397 private void treeView_Click(object sender, EventArgs e) {
399 MouseEventArgs m = e as MouseEventArgs;
400 if (m == null || m.Button != MouseButtons.Right)
403 NodeControlInfo info = treeView.GetNodeControlInfoAt(
406 treeView.SelectedNode = info.Node;
407 if (info.Node != null) {
408 SensorNode node = info.Node.Tag as SensorNode;
409 if (node != null && node.Sensor != null) {
410 sensorContextMenu.MenuItems.Clear();
411 if (node.Sensor.Parameters.Length > 0) {
412 MenuItem item = new MenuItem("Parameters...");
413 item.Click += delegate(object obj, EventArgs args) {
414 ShowParameterForm(node.Sensor);
416 sensorContextMenu.MenuItems.Add(item);
418 if (nodeTextBoxText.EditEnabled) {
419 MenuItem item = new MenuItem("Rename");
420 item.Click += delegate(object obj, EventArgs args) {
421 nodeTextBoxText.BeginEdit();
423 sensorContextMenu.MenuItems.Add(item);
425 if (node.IsVisible) {
426 MenuItem item = new MenuItem("Hide");
427 item.Click += delegate(object obj, EventArgs args) {
428 node.IsVisible = false;
430 sensorContextMenu.MenuItems.Add(item);
432 MenuItem item = new MenuItem("Unhide");
433 item.Click += delegate(object obj, EventArgs args) {
434 node.IsVisible = true;
436 sensorContextMenu.MenuItems.Add(item);
438 sensorContextMenu.MenuItems.Add(new MenuItem("-"));
440 MenuItem item = new MenuItem("Show in Tray");
441 item.Checked = systemTray.Contains(node.Sensor);
442 item.Click += delegate(object obj, EventArgs args) {
444 systemTray.Remove(node.Sensor);
446 systemTray.Add(node.Sensor, true);
448 sensorContextMenu.MenuItems.Add(item);
450 if (gadget != null) {
451 MenuItem item = new MenuItem("Show in Gadget");
452 item.Checked = gadget.Contains(node.Sensor);
453 item.Click += delegate(object obj, EventArgs args) {
455 gadget.Remove(node.Sensor);
457 gadget.Add(node.Sensor);
460 sensorContextMenu.MenuItems.Add(item);
463 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
468 private void saveReportMenuItem_Click(object sender, EventArgs e) {
469 string report = computer.GetReport();
470 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
471 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
477 private void SysTrayHideShow() {
483 protected override void WndProc(ref Message m) {
484 const int WM_SYSCOMMAND = 0x112;
485 const int SC_MINIMIZE = 0xF020;
486 const int SC_CLOSE = 0xF060;
488 if (minimizeToTray.Value &&
489 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
491 } else if(minimizeOnClose.Value &&
492 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) {
494 * Apparently the user wants to minimize rather than close
495 * Now we still need to check if we're going to the tray or not
497 * Note: the correct way to do this would be to send out SC_MINIMIZE,
498 * but since the code here is so simple,
499 * that would just be a waste of time.
501 if (minimizeToTray.Value)
504 WindowState = FormWindowState.Minimized;
510 private void hideShowClick(object sender, EventArgs e) {
514 private void ShowParameterForm(ISensor sensor) {
515 ParameterForm form = new ParameterForm();
516 form.Parameters = sensor.Parameters;
517 form.captionLabel.Text = sensor.Name;
521 private void treeView_NodeMouseDoubleClick(object sender,
522 TreeNodeAdvMouseEventArgs e) {
523 SensorNode node = e.Node.Tag as SensorNode;
524 if (node != null && node.Sensor != null &&
525 node.Sensor.Parameters.Length > 0) {
526 ShowParameterForm(node.Sensor);
530 private void celciusMenuItem_Click(object sender, EventArgs e) {
531 celciusMenuItem.Checked = true;
532 fahrenheitMenuItem.Checked = false;
533 unitManager.TemperatureUnit = TemperatureUnit.Celcius;
536 private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
537 celciusMenuItem.Checked = false;
538 fahrenheitMenuItem.Checked = true;
539 unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
542 private void sumbitReportMenuItem_Click(object sender, EventArgs e)
544 ReportForm form = new ReportForm();
545 form.Report = computer.GetReport();
549 private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
550 computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
556 private void MainForm_MoveOrResize(object sender, EventArgs e) {
557 if (WindowState != FormWindowState.Minimized) {
558 settings.SetValue("mainForm.Location.X", Bounds.X);
559 settings.SetValue("mainForm.Location.Y", Bounds.Y);
560 settings.SetValue("mainForm.Width", Bounds.Width);
561 settings.SetValue("mainForm.Height", Bounds.Height);