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.
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.
40 using System.Drawing.Drawing2D;
41 using System.Drawing.Imaging;
42 using System.Drawing.Text;
43 using System.Runtime.InteropServices;
44 using System.Windows.Forms;
45 using OpenHardwareMonitor.Hardware;
46 using OpenHardwareMonitor.Utilities;
48 namespace OpenHardwareMonitor.GUI {
49 public class SensorNotifyIcon : IDisposable {
51 private ISensor sensor;
52 private NotifyIcon notifyIcon;
53 private Bitmap bitmap;
54 private Graphics graphics;
56 private Color darkColor;
58 private Brush darkBrush;
62 public SensorNotifyIcon(SystemTray sensorSystemTray, ISensor sensor,
63 bool balloonTip, PersistentSettings settings)
66 this.notifyIcon = new NotifyIcon();
68 Color defaultColor = Color.Black;
69 if (sensor.SensorType == SensorType.Load ||
70 sensor.SensorType == SensorType.Control ||
71 sensor.SensorType == SensorType.Level)
73 defaultColor = Color.FromArgb(0xff, 0x70, 0x8c, 0xf1);
75 Color = settings.GetValue(new Identifier(sensor.Identifier,
76 "traycolor").ToString(), defaultColor);
78 this.pen = new Pen(Color.FromArgb(96, Color.Black));
79 this.font = SystemFonts.MessageBoxFont;
81 ContextMenu contextMenu = new ContextMenu();
82 MenuItem hideShowItem = new MenuItem("Hide/Show");
83 hideShowItem.Click += delegate(object obj, EventArgs args) {
84 sensorSystemTray.SendHideShowCommand();
86 contextMenu.MenuItems.Add(hideShowItem);
87 contextMenu.MenuItems.Add(new MenuItem("-"));
88 MenuItem removeItem = new MenuItem("Remove Sensor");
89 removeItem.Click += delegate(object obj, EventArgs args) {
90 sensorSystemTray.Remove(this.sensor);
92 contextMenu.MenuItems.Add(removeItem);
93 MenuItem colorItem = new MenuItem("Change Color...");
94 colorItem.Click += delegate(object obj, EventArgs args) {
95 ColorDialog dialog = new ColorDialog();
97 if (dialog.ShowDialog() == DialogResult.OK) {
99 settings.SetValue(new Identifier(sensor.Identifier,
100 "traycolor").ToString(), Color);
103 contextMenu.MenuItems.Add(colorItem);
104 contextMenu.MenuItems.Add(new MenuItem("-"));
105 MenuItem exitItem = new MenuItem("Exit");
106 exitItem.Click += delegate(object obj, EventArgs args) {
107 sensorSystemTray.SendExitCommand();
109 contextMenu.MenuItems.Add(exitItem);
110 this.notifyIcon.ContextMenu = contextMenu;
111 this.notifyIcon.DoubleClick += delegate(object obj, EventArgs args) {
112 sensorSystemTray.SendHideShowCommand();
115 this.bitmap = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
116 this.graphics = Graphics.FromImage(this.bitmap);
118 if (Environment.OSVersion.Version.Major > 5) {
119 this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
120 this.graphics.SmoothingMode = SmoothingMode.HighQuality;
124 public ISensor Sensor {
125 get { return sensor; }
129 get { return color; }
132 this.darkColor = Color.FromArgb(255,
136 Brush brush = this.brush;
137 this.brush = new SolidBrush(this.color);
140 Brush darkBrush = this.darkBrush;
141 this.darkBrush = new SolidBrush(this.darkColor);
142 if (darkBrush != null)
147 public void Dispose() {
148 Icon icon = notifyIcon.Icon;
149 notifyIcon.Icon = null;
152 notifyIcon.Dispose();
156 if (darkBrush != null)
163 private string GetString() {
164 switch (sensor.SensorType) {
165 case SensorType.Voltage:
166 return string.Format("{0:F11}", sensor.Value);
167 case SensorType.Clock:
168 return string.Format("{0:F11}", 1e-3f * sensor.Value);
169 case SensorType.Load:
170 return string.Format("{0:F0}", sensor.Value);
171 case SensorType.Temperature:
172 return string.Format("{0:F0}", sensor.Value);
174 return string.Format("{0:F11}", 1e-3f * sensor.Value);
175 case SensorType.Flow:
176 return string.Format("{0:F11}", 1e-3f * sensor.Value);
177 case SensorType.Control:
178 return string.Format("{0:F0}", sensor.Value);
179 case SensorType.Level:
180 return string.Format("{0:F0}", sensor.Value);
185 private Icon CreateTransparentIcon() {
187 graphics.Clear(Color.Black);
188 TextRenderer.DrawText(graphics, GetString(), font,
189 new Point(-2, 0), Color.White, Color.Black);
191 BitmapData data = bitmap.LockBits(
192 new Rectangle(0, 0, bitmap.Width, bitmap.Height),
193 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
195 IntPtr Scan0 = data.Scan0;
197 int numBytes = bitmap.Width * bitmap.Height * 4;
198 byte[] bytes = new byte[numBytes];
199 Marshal.Copy(Scan0, bytes, 0, numBytes);
200 bitmap.UnlockBits(data);
202 byte red, green, blue;
203 for (int i = 0; i < bytes.Length; i += 4) {
205 green = bytes[i + 1];
209 bytes[i + 1] = color.G;
210 bytes[i + 2] = color.R;
211 bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
214 return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
217 private Icon CreatePercentageIcon() {
219 graphics.Clear(Color.Transparent);
220 } catch (ArgumentException) {
221 graphics.Clear(Color.Black);
223 graphics.FillRectangle(darkBrush, 0.5f, -0.5f, 14, 16);
224 float y = 0.16f * (100 - sensor.Value.Value);
225 graphics.FillRectangle(brush, 0.5f, -0.5f + y, 14, 16 - y);
226 graphics.DrawRectangle(pen, 1, 0, 13, 15);
228 BitmapData data = bitmap.LockBits(
229 new Rectangle(0, 0, bitmap.Width, bitmap.Height),
230 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
231 byte[] bytes = new byte[bitmap.Width * bitmap.Height * 4];
232 Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
233 bitmap.UnlockBits(data);
235 return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
238 public void Update() {
239 Icon icon = notifyIcon.Icon;
241 switch (sensor.SensorType) {
242 case SensorType.Load:
243 case SensorType.Control:
244 case SensorType.Level:
245 notifyIcon.Icon = CreatePercentageIcon();
248 notifyIcon.Icon = CreateTransparentIcon();
256 switch (sensor.SensorType) {
257 case SensorType.Voltage: format = "\n{0}: {1:F2} V"; break;
258 case SensorType.Clock: format = "\n{0}: {1:F0} MHz"; break;
259 case SensorType.Load: format = "\n{0}: {1:F1} %"; break;
260 case SensorType.Temperature: format = "\n{0}: {1:F1} °C"; break;
261 case SensorType.Fan: format = "\n{0}: {1:F0} RPM"; break;
262 case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
263 case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
264 case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
266 string formattedValue = string.Format(format, sensor.Name, sensor.Value);
267 string hardwareName = sensor.Hardware.Name;
268 hardwareName = hardwareName.Substring(0,
269 Math.Min(63 - formattedValue.Length, hardwareName.Length));
270 string text = hardwareName + formattedValue;
271 if (text.Length > 63)
274 notifyIcon.Text = text;
275 notifyIcon.Visible = true;