GUI/SensorNotifyIcon.cs
author moel.mich
Fri, 12 Feb 2010 00:36:56 +0000
changeset 40 2392f7402fb6
child 42 47385d4fc990
permissions -rw-r--r--
First system tray sensor monitor support.
moel@40
     1
/*
moel@40
     2
  
moel@40
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@40
     4
moel@40
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@40
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@40
     7
  the License. You may obtain a copy of the License at
moel@40
     8
 
moel@40
     9
  http://www.mozilla.org/MPL/
moel@40
    10
moel@40
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@40
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@40
    13
  for the specific language governing rights and limitations under the License.
moel@40
    14
moel@40
    15
  The Original Code is the Open Hardware Monitor code.
moel@40
    16
moel@40
    17
  The Initial Developer of the Original Code is 
moel@40
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@40
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@40
    20
  the Initial Developer. All Rights Reserved.
moel@40
    21
moel@40
    22
  Contributor(s):
moel@40
    23
moel@40
    24
  Alternatively, the contents of this file may be used under the terms of
moel@40
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@40
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@40
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@40
    28
  of those above. If you wish to allow use of your version of this file only
moel@40
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@40
    30
  use your version of this file under the terms of the MPL, indicate your
moel@40
    31
  decision by deleting the provisions above and replace them with the notice
moel@40
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@40
    33
  the provisions above, a recipient may use your version of this file under
moel@40
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@40
    35
 
moel@40
    36
*/
moel@40
    37
moel@40
    38
using System;
moel@40
    39
using System.Collections.Generic;
moel@40
    40
using System.Drawing;
moel@40
    41
using System.Drawing.Drawing2D;
moel@40
    42
using System.Drawing.Imaging;
moel@40
    43
using System.Drawing.Text;
moel@40
    44
using System.Text;
moel@40
    45
using System.Windows.Forms;
moel@40
    46
using System.Runtime.InteropServices;
moel@40
    47
using OpenHardwareMonitor.Hardware;
moel@40
    48
using OpenHardwareMonitor.Utilities;
moel@40
    49
moel@40
    50
namespace OpenHardwareMonitor.GUI {
moel@40
    51
  public class SensorNotifyIcon : IDisposable {
moel@40
    52
moel@40
    53
    private ISensor sensor;
moel@40
    54
    private NotifyIcon notifyIcon;
moel@40
    55
    private Bitmap bitmap;
moel@40
    56
    private Graphics graphics;
moel@40
    57
    private int majorVersion;
moel@40
    58
moel@40
    59
    public SensorNotifyIcon(SensorSystemTray sensorSystemTray, ISensor sensor) {
moel@40
    60
      this.sensor = sensor;
moel@40
    61
      this.notifyIcon = new NotifyIcon();
moel@40
    62
      this.majorVersion = Environment.OSVersion.Version.Major;      
moel@40
    63
      
moel@40
    64
      ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
moel@40
    65
      ToolStripMenuItem item = new ToolStripMenuItem("Remove");
moel@40
    66
      item.Click += delegate(object obj, EventArgs args) {
moel@40
    67
        sensorSystemTray.Remove(sensor);
moel@40
    68
      };
moel@40
    69
      contextMenuStrip.Items.Add(item);
moel@40
    70
      this.notifyIcon.ContextMenuStrip = contextMenuStrip;
moel@40
    71
moel@40
    72
      this.bitmap = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
moel@40
    73
      this.graphics = Graphics.FromImage(this.bitmap);
moel@40
    74
      this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
moel@40
    75
      this.graphics.SmoothingMode = SmoothingMode.HighQuality;
moel@40
    76
    }
moel@40
    77
moel@40
    78
    public ISensor Sensor {
moel@40
    79
      get { return sensor; }
moel@40
    80
    }
moel@40
    81
moel@40
    82
    public void Dispose() {      
moel@40
    83
      Icon icon = notifyIcon.Icon;
moel@40
    84
      notifyIcon.Icon = null;
moel@40
    85
      if (icon != null)
moel@40
    86
        icon.Dispose();      
moel@40
    87
      notifyIcon.Dispose();
moel@40
    88
      notifyIcon = null;
moel@40
    89
moel@40
    90
      graphics.Dispose();
moel@40
    91
      graphics = null;
moel@40
    92
      bitmap.Dispose();
moel@40
    93
      bitmap = null;
moel@40
    94
    }
moel@40
    95
moel@40
    96
    private string GetString() {
moel@40
    97
      switch (sensor.SensorType) {
moel@40
    98
        case SensorType.Voltage:
moel@40
    99
          return string.Format("{0:F11}", sensor.Value);
moel@40
   100
        case SensorType.Clock:
moel@40
   101
          return string.Format("{0:F11}", 1e-3f * sensor.Value);
moel@40
   102
        case SensorType.Load: 
moel@40
   103
          return string.Format("{0:F0}", sensor.Value < 99 ? sensor.Value : 99);
moel@40
   104
        case SensorType.Temperature: 
moel@40
   105
          return string.Format("{0:F0}", sensor.Value);
moel@40
   106
        case SensorType.Fan: 
moel@40
   107
          return string.Format("{0:F11}", 1e-3f * sensor.Value);
moel@40
   108
      }
moel@40
   109
      return "-";
moel@40
   110
    }
moel@40
   111
moel@40
   112
    private Icon CreateSimpleIcon() {
moel@40
   113
moel@40
   114
      graphics.Clear(SystemColors.ButtonFace);
moel@40
   115
      TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
moel@40
   116
        new Point(-2, 0), Color.Blue, SystemColors.ButtonFace);
moel@40
   117
moel@40
   118
      BitmapData data = bitmap.LockBits(
moel@40
   119
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
moel@40
   120
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
moel@40
   121
moel@40
   122
      int stride = data.Stride;
moel@40
   123
      IntPtr Scan0 = data.Scan0;
moel@40
   124
moel@40
   125
      int numBytes = bitmap.Width * bitmap.Height * 4;
moel@40
   126
      byte[] bytes = new byte[numBytes];
moel@40
   127
      Marshal.Copy(Scan0, bytes, 0, numBytes);
moel@40
   128
      bitmap.UnlockBits(data);
moel@40
   129
moel@40
   130
      return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
moel@40
   131
    }
moel@40
   132
moel@40
   133
    private Icon CreateTransparentIcon() {
moel@40
   134
moel@40
   135
      graphics.Clear(Color.Black);
moel@40
   136
      TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
moel@40
   137
        new Point(-2, 0), Color.White, Color.Black);
moel@40
   138
moel@40
   139
      BitmapData data = bitmap.LockBits(
moel@40
   140
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
moel@40
   141
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
moel@40
   142
moel@40
   143
      int stride = data.Stride;
moel@40
   144
      IntPtr Scan0 = data.Scan0;
moel@40
   145
moel@40
   146
      int numBytes = bitmap.Width * bitmap.Height * 4;
moel@40
   147
      byte[] bytes = new byte[numBytes];
moel@40
   148
      Marshal.Copy(Scan0, bytes, 0, numBytes);
moel@40
   149
      bitmap.UnlockBits(data);
moel@40
   150
moel@40
   151
      byte red, green, blue;
moel@40
   152
      for (int i = 0; i < bytes.Length; i += 4) {
moel@40
   153
        blue = bytes[i];
moel@40
   154
        green = bytes[i + 1];
moel@40
   155
        red = bytes[i + 2];
moel@40
   156
moel@40
   157
        bytes[i] = 255;
moel@40
   158
        bytes[i + 1] = 255;
moel@40
   159
        bytes[i + 2] = 255;
moel@40
   160
        bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
moel@40
   161
      }
moel@40
   162
moel@40
   163
      return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
moel@40
   164
    }
moel@40
   165
moel@40
   166
    public void Update() {
moel@40
   167
      Icon icon = notifyIcon.Icon;
moel@40
   168
moel@40
   169
      if (majorVersion < 6) {
moel@40
   170
        notifyIcon.Icon = CreateSimpleIcon();
moel@40
   171
      } else {
moel@40
   172
        notifyIcon.Icon = CreateTransparentIcon();
moel@40
   173
      }
moel@40
   174
      
moel@40
   175
      if (icon != null) 
moel@40
   176
        icon.Dispose();
moel@40
   177
moel@40
   178
      string format = "";
moel@40
   179
      switch (sensor.SensorType) {
moel@40
   180
        case SensorType.Voltage: format = "{0}\n{1}: {2:F2} V"; break;
moel@40
   181
        case SensorType.Clock: format = "{0}\n{1}: {2:F0} MHz"; break;
moel@40
   182
        case SensorType.Load: format = "{0}\n{1}: {2:F1} %"; break;
moel@40
   183
        case SensorType.Temperature: format = "{0}\n{1}: {2:F1} °C"; break;
moel@40
   184
        case SensorType.Fan: format = "{0}\n{1}: {2:F0} RPM"; break;
moel@40
   185
      }
moel@40
   186
moel@40
   187
      notifyIcon.Text = string.Format(format, 
moel@40
   188
        sensor.Hardware.Name, sensor.Name, sensor.Value);
moel@40
   189
      notifyIcon.Visible = true;
moel@40
   190
    }
moel@40
   191
  }
moel@40
   192
}