1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/GUI/SensorNotifyIcon.cs Fri Feb 12 00:36:56 2010 +0000
1.3 @@ -0,0 +1,192 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.Drawing;
1.44 +using System.Drawing.Drawing2D;
1.45 +using System.Drawing.Imaging;
1.46 +using System.Drawing.Text;
1.47 +using System.Text;
1.48 +using System.Windows.Forms;
1.49 +using System.Runtime.InteropServices;
1.50 +using OpenHardwareMonitor.Hardware;
1.51 +using OpenHardwareMonitor.Utilities;
1.52 +
1.53 +namespace OpenHardwareMonitor.GUI {
1.54 + public class SensorNotifyIcon : IDisposable {
1.55 +
1.56 + private ISensor sensor;
1.57 + private NotifyIcon notifyIcon;
1.58 + private Bitmap bitmap;
1.59 + private Graphics graphics;
1.60 + private int majorVersion;
1.61 +
1.62 + public SensorNotifyIcon(SensorSystemTray sensorSystemTray, ISensor sensor) {
1.63 + this.sensor = sensor;
1.64 + this.notifyIcon = new NotifyIcon();
1.65 + this.majorVersion = Environment.OSVersion.Version.Major;
1.66 +
1.67 + ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
1.68 + ToolStripMenuItem item = new ToolStripMenuItem("Remove");
1.69 + item.Click += delegate(object obj, EventArgs args) {
1.70 + sensorSystemTray.Remove(sensor);
1.71 + };
1.72 + contextMenuStrip.Items.Add(item);
1.73 + this.notifyIcon.ContextMenuStrip = contextMenuStrip;
1.74 +
1.75 + this.bitmap = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
1.76 + this.graphics = Graphics.FromImage(this.bitmap);
1.77 + this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
1.78 + this.graphics.SmoothingMode = SmoothingMode.HighQuality;
1.79 + }
1.80 +
1.81 + public ISensor Sensor {
1.82 + get { return sensor; }
1.83 + }
1.84 +
1.85 + public void Dispose() {
1.86 + Icon icon = notifyIcon.Icon;
1.87 + notifyIcon.Icon = null;
1.88 + if (icon != null)
1.89 + icon.Dispose();
1.90 + notifyIcon.Dispose();
1.91 + notifyIcon = null;
1.92 +
1.93 + graphics.Dispose();
1.94 + graphics = null;
1.95 + bitmap.Dispose();
1.96 + bitmap = null;
1.97 + }
1.98 +
1.99 + private string GetString() {
1.100 + switch (sensor.SensorType) {
1.101 + case SensorType.Voltage:
1.102 + return string.Format("{0:F11}", sensor.Value);
1.103 + case SensorType.Clock:
1.104 + return string.Format("{0:F11}", 1e-3f * sensor.Value);
1.105 + case SensorType.Load:
1.106 + return string.Format("{0:F0}", sensor.Value < 99 ? sensor.Value : 99);
1.107 + case SensorType.Temperature:
1.108 + return string.Format("{0:F0}", sensor.Value);
1.109 + case SensorType.Fan:
1.110 + return string.Format("{0:F11}", 1e-3f * sensor.Value);
1.111 + }
1.112 + return "-";
1.113 + }
1.114 +
1.115 + private Icon CreateSimpleIcon() {
1.116 +
1.117 + graphics.Clear(SystemColors.ButtonFace);
1.118 + TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
1.119 + new Point(-2, 0), Color.Blue, SystemColors.ButtonFace);
1.120 +
1.121 + BitmapData data = bitmap.LockBits(
1.122 + new Rectangle(0, 0, bitmap.Width, bitmap.Height),
1.123 + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
1.124 +
1.125 + int stride = data.Stride;
1.126 + IntPtr Scan0 = data.Scan0;
1.127 +
1.128 + int numBytes = bitmap.Width * bitmap.Height * 4;
1.129 + byte[] bytes = new byte[numBytes];
1.130 + Marshal.Copy(Scan0, bytes, 0, numBytes);
1.131 + bitmap.UnlockBits(data);
1.132 +
1.133 + return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
1.134 + }
1.135 +
1.136 + private Icon CreateTransparentIcon() {
1.137 +
1.138 + graphics.Clear(Color.Black);
1.139 + TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
1.140 + new Point(-2, 0), Color.White, Color.Black);
1.141 +
1.142 + BitmapData data = bitmap.LockBits(
1.143 + new Rectangle(0, 0, bitmap.Width, bitmap.Height),
1.144 + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
1.145 +
1.146 + int stride = data.Stride;
1.147 + IntPtr Scan0 = data.Scan0;
1.148 +
1.149 + int numBytes = bitmap.Width * bitmap.Height * 4;
1.150 + byte[] bytes = new byte[numBytes];
1.151 + Marshal.Copy(Scan0, bytes, 0, numBytes);
1.152 + bitmap.UnlockBits(data);
1.153 +
1.154 + byte red, green, blue;
1.155 + for (int i = 0; i < bytes.Length; i += 4) {
1.156 + blue = bytes[i];
1.157 + green = bytes[i + 1];
1.158 + red = bytes[i + 2];
1.159 +
1.160 + bytes[i] = 255;
1.161 + bytes[i + 1] = 255;
1.162 + bytes[i + 2] = 255;
1.163 + bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
1.164 + }
1.165 +
1.166 + return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
1.167 + }
1.168 +
1.169 + public void Update() {
1.170 + Icon icon = notifyIcon.Icon;
1.171 +
1.172 + if (majorVersion < 6) {
1.173 + notifyIcon.Icon = CreateSimpleIcon();
1.174 + } else {
1.175 + notifyIcon.Icon = CreateTransparentIcon();
1.176 + }
1.177 +
1.178 + if (icon != null)
1.179 + icon.Dispose();
1.180 +
1.181 + string format = "";
1.182 + switch (sensor.SensorType) {
1.183 + case SensorType.Voltage: format = "{0}\n{1}: {2:F2} V"; break;
1.184 + case SensorType.Clock: format = "{0}\n{1}: {2:F0} MHz"; break;
1.185 + case SensorType.Load: format = "{0}\n{1}: {2:F1} %"; break;
1.186 + case SensorType.Temperature: format = "{0}\n{1}: {2:F1} °C"; break;
1.187 + case SensorType.Fan: format = "{0}\n{1}: {2:F0} RPM"; break;
1.188 + }
1.189 +
1.190 + notifyIcon.Text = string.Format(format,
1.191 + sensor.Hardware.Name, sensor.Name, sensor.Value);
1.192 + notifyIcon.Visible = true;
1.193 + }
1.194 + }
1.195 +}