Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.ComponentModel;
15 using System.Drawing.Drawing2D;
16 using System.Windows.Forms;
17 using OpenHardwareMonitor.Hardware;
19 namespace OpenHardwareMonitor.GUI {
20 public class PlotPanel : UserControl {
22 private PersistentSettings settings;
25 private List<ISensor> clocks = new List<ISensor>();
26 private List<ISensor> temperatures = new List<ISensor>();
27 private List<ISensor> fans = new List<ISensor>();
28 private IDictionary<ISensor, Color> colors;
30 private StringFormat centerlower;
31 private StringFormat centerleft;
32 private StringFormat lowerleft;
33 private Brush lightBrush;
36 private UserRadioGroup timeWindowRadioGroup;
38 public PlotPanel(PersistentSettings settings) {
39 this.settings = settings;
41 this.SetStyle(ControlStyles.DoubleBuffer |
42 ControlStyles.UserPaint |
43 ControlStyles.AllPaintingInWmPaint |
44 ControlStyles.ResizeRedraw, true);
49 centerlower = new StringFormat();
50 centerlower.Alignment = StringAlignment.Center;
51 centerlower.LineAlignment = StringAlignment.Near;
53 centerleft = new StringFormat();
54 centerleft.Alignment = StringAlignment.Far;
55 centerleft.LineAlignment = StringAlignment.Center;
57 lowerleft = new StringFormat();
58 lowerleft.Alignment = StringAlignment.Far;
59 lowerleft.LineAlignment = StringAlignment.Near;
61 lightBrush = new SolidBrush(Color.FromArgb(245, 245, 245));
62 lightPen = new Pen(Color.FromArgb(200, 200, 200));
65 private void CreateContextMenu() {
66 MenuItem timeWindow = new MenuItem("Time Scale");
68 MenuItem[] timeWindowMenuItems =
69 { new MenuItem("Auto"),
70 new MenuItem("5 min"),
71 new MenuItem("10 min"),
72 new MenuItem("20 min"),
73 new MenuItem("30 min"),
74 new MenuItem("45 min"),
76 new MenuItem("1.5 h"),
81 new MenuItem("24 h") };
83 foreach (MenuItem mi in timeWindowMenuItems)
84 timeWindow.MenuItems.Add(mi);
86 timeWindowRadioGroup = new UserRadioGroup("timeWindow", 0,
87 timeWindowMenuItems, settings);
89 this.ContextMenu = new ContextMenu();
90 this.ContextMenu.MenuItems.Add(timeWindow);
93 private List<float> GetTemperatureGrid() {
95 float? minTempNullable = null;
96 float? maxTempNullable = null;
97 foreach (ISensor sensor in temperatures) {
98 IEnumerable<SensorValue> values = sensor.Values;
99 foreach (SensorValue value in values) {
100 if (!float.IsNaN(value.Value)) {
101 if (!minTempNullable.HasValue || minTempNullable > value.Value)
102 minTempNullable = value.Value;
103 if (!maxTempNullable.HasValue || maxTempNullable < value.Value)
104 maxTempNullable = value.Value;
108 if (!minTempNullable.HasValue) {
109 minTempNullable = 20;
110 maxTempNullable = 30;
113 float maxTemp = (float)Math.Ceiling(maxTempNullable.Value / 10) * 10;
114 float minTemp = (float)Math.Floor(minTempNullable.Value / 10) * 10;
115 if (maxTemp == minTemp)
118 int countTempMax = 4;
119 float deltaTemp = maxTemp - minTemp;
120 int countTemp = (int)Math.Round(deltaTemp / 2);
121 if (countTemp > countTempMax)
122 countTemp = (int)Math.Round(deltaTemp / 5);
123 if (countTemp > countTempMax)
124 countTemp = (int)Math.Round(deltaTemp / 10);
125 if (countTemp > countTempMax)
126 countTemp = (int)Math.Round(deltaTemp / 20);
128 List<float> grid = new List<float>(countTemp + 1);
129 for (int i = 0; i <= countTemp; i++) {
130 grid.Add(minTemp + i * deltaTemp / countTemp);
135 private List<float> GetTimeGrid() {
138 if (timeWindowRadioGroup.Value == 0) { // Auto
140 if (temperatures.Count > 0) {
141 IEnumerator<SensorValue> enumerator =
142 temperatures[0].Values.GetEnumerator();
143 if (enumerator.MoveNext()) {
144 maxTime = (float)(now - enumerator.Current.Time).TotalMinutes;
149 { 5, 10, 20, 30, 45, 60, 90, 120, 180, 360, 720, 1440 };
151 maxTime = maxTimes[timeWindowRadioGroup.Value - 1];
156 while (deltaTime + 1 <= maxTime && deltaTime < 10)
158 while (deltaTime + 2 <= maxTime && deltaTime < 30)
160 while (deltaTime + 5 <= maxTime && deltaTime < 100)
162 while (deltaTime + 50 <= maxTime && deltaTime < 1000)
164 while (deltaTime + 100 <= maxTime && deltaTime < 10000)
167 List<float> grid = new List<float>(countTime + 1);
168 for (int i = 0; i <= countTime; i++) {
169 grid.Add(i * deltaTime / countTime);
174 protected override void OnPaint(PaintEventArgs e) {
175 now = DateTime.UtcNow - new TimeSpan(0, 0, 4);
177 List<float> timeGrid = GetTimeGrid();
178 List<float> tempGrid = GetTemperatureGrid();
180 Graphics g = e.Graphics;
183 new RectangleF(0, 0, Bounds.Width, Bounds.Height);
188 float w = r.Width - ml - mr;
193 float h = r.Height - mt - mb;
195 float leftScaleSpace = 5;
196 float bottomScaleSpace = 5;
198 g.Clear(Color.White);
200 if (w > 0 && h > 0) {
201 g.FillRectangle(lightBrush, x0, y0, w, h);
203 g.SmoothingMode = SmoothingMode.HighQuality;
204 for (int i = 0; i < timeGrid.Count; i++) {
205 float x = x0 + i * w / (timeGrid.Count - 1);
206 g.DrawLine(lightPen, x, y0, x, y0 + h);
209 for (int i = 0; i < tempGrid.Count; i++) {
210 float y = y0 + i * h / (tempGrid.Count - 1);
211 g.DrawLine(lightPen, x0, y, x0 + w, y);
214 float deltaTemp = tempGrid[tempGrid.Count - 1] - tempGrid[0];
215 float deltaTime = timeGrid[timeGrid.Count - 1];
216 foreach (ISensor sensor in temperatures) {
217 using (Pen pen = new Pen(colors[sensor])) {
218 IEnumerable<SensorValue> values = sensor.Values;
219 PointF last = new PointF();
221 foreach (SensorValue v in values) {
222 if (!float.IsNaN(v.Value)) {
223 PointF point = new PointF(
224 x0 + w - w * (float)(now - v.Time).TotalMinutes / deltaTime,
225 y0 + h - h * (v.Value - tempGrid[0]) / deltaTemp);
227 g.DrawLine(pen, last, point);
237 g.SmoothingMode = SmoothingMode.None;
238 g.FillRectangle(Brushes.White, 0, 0, x0, r.Height);
239 g.FillRectangle(Brushes.White, x0 + w + 1, 0, r.Width - x0 - w,
242 for (int i = 1; i < timeGrid.Count; i++) {
243 float x = x0 + (timeGrid.Count - 1 - i) * w / (timeGrid.Count - 1);
244 g.DrawString(timeGrid[i].ToString(), Font, Brushes.Black, x,
245 y0 + h + bottomScaleSpace, centerlower);
248 for (int i = 0; i < tempGrid.Count - 1; i++) {
249 float y = y0 + (tempGrid.Count - 1 - i) * h / (tempGrid.Count - 1);
250 g.DrawString(tempGrid[i].ToString(), Font, Brushes.Black,
251 x0 - leftScaleSpace, y, centerleft);
254 g.SmoothingMode = SmoothingMode.HighQuality;
255 g.DrawString("[°C]", Font, Brushes.Black, x0 - leftScaleSpace, y0,
257 g.DrawString("[min]", Font, Brushes.Black, x0 + w,
258 y0 + h + bottomScaleSpace, lowerleft);
262 public void SetSensors(List<ISensor> sensors,
263 IDictionary<ISensor, Color> colors) {
264 this.colors = colors;
265 List<ISensor> clocks = new List<ISensor>();
266 List<ISensor> temperatures = new List<ISensor>();
267 List<ISensor> fans = new List<ISensor>();
268 foreach (ISensor sensor in sensors)
269 switch (sensor.SensorType) {
270 case SensorType.Clock: clocks.Add(sensor); break;
271 case SensorType.Temperature: temperatures.Add(sensor); break;
272 case SensorType.Fan: fans.Add(sensor); break;
274 this.clocks = clocks;
275 this.temperatures = temperatures;