GUI/SensorNotifyIcon.cs
author moel.mich
Fri, 12 Feb 2010 22:46:31 +0000
changeset 42 47385d4fc990
parent 40 2392f7402fb6
child 43 5b7398d061b7
permissions -rw-r--r--
Tray sensor display default color is black and color can be changed now. Fixed CPU load reading for AMD CPUs and added additional misc device for AMD core temperature reading.
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@42
    58
    private Color color;
moel@40
    59
moel@42
    60
    public SensorNotifyIcon(SensorSystemTray sensorSystemTray, ISensor sensor,
moel@42
    61
      bool balloonTip) 
moel@42
    62
    {
moel@40
    63
      this.sensor = sensor;
moel@40
    64
      this.notifyIcon = new NotifyIcon();
moel@42
    65
      this.majorVersion = Environment.OSVersion.Version.Major;
moel@42
    66
      this.color = Config.Get(sensor.Identifier + "/traycolor", Color.Black);
moel@40
    67
      
moel@40
    68
      ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
moel@42
    69
      ToolStripMenuItem removeItem = new ToolStripMenuItem("Remove");
moel@42
    70
      removeItem.Click += delegate(object obj, EventArgs args) {
moel@42
    71
        sensorSystemTray.Remove(this.sensor);
moel@40
    72
      };
moel@42
    73
      contextMenuStrip.Items.Add(removeItem);
moel@42
    74
      ToolStripMenuItem colorItem = new ToolStripMenuItem("Change Color...");
moel@42
    75
      colorItem.Click += delegate(object obj, EventArgs args) {
moel@42
    76
        ColorDialog dialog = new ColorDialog();
moel@42
    77
        dialog.Color = this.color;
moel@42
    78
        if (dialog.ShowDialog() == DialogResult.OK) {
moel@42
    79
          this.color = dialog.Color;
moel@42
    80
          Config.Set(sensor.Identifier + "/traycolor", this.color);
moel@42
    81
        }
moel@42
    82
      };
moel@42
    83
      contextMenuStrip.Items.Add(colorItem);
moel@40
    84
      this.notifyIcon.ContextMenuStrip = contextMenuStrip;
moel@40
    85
moel@40
    86
      this.bitmap = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
moel@40
    87
      this.graphics = Graphics.FromImage(this.bitmap);
moel@40
    88
      this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
moel@40
    89
      this.graphics.SmoothingMode = SmoothingMode.HighQuality;
moel@40
    90
    }
moel@40
    91
moel@40
    92
    public ISensor Sensor {
moel@40
    93
      get { return sensor; }
moel@40
    94
    }
moel@40
    95
moel@42
    96
    public Color Color {
moel@42
    97
      get { return color; }
moel@42
    98
      set { color = value; }
moel@42
    99
    }
moel@42
   100
moel@40
   101
    public void Dispose() {      
moel@40
   102
      Icon icon = notifyIcon.Icon;
moel@40
   103
      notifyIcon.Icon = null;
moel@40
   104
      if (icon != null)
moel@40
   105
        icon.Dispose();      
moel@40
   106
      notifyIcon.Dispose();
moel@40
   107
      notifyIcon = null;
moel@40
   108
moel@40
   109
      graphics.Dispose();
moel@40
   110
      graphics = null;
moel@40
   111
      bitmap.Dispose();
moel@40
   112
      bitmap = null;
moel@40
   113
    }
moel@40
   114
moel@40
   115
    private string GetString() {
moel@40
   116
      switch (sensor.SensorType) {
moel@40
   117
        case SensorType.Voltage:
moel@40
   118
          return string.Format("{0:F11}", sensor.Value);
moel@40
   119
        case SensorType.Clock:
moel@40
   120
          return string.Format("{0:F11}", 1e-3f * sensor.Value);
moel@40
   121
        case SensorType.Load: 
moel@40
   122
          return string.Format("{0:F0}", sensor.Value < 99 ? sensor.Value : 99);
moel@40
   123
        case SensorType.Temperature: 
moel@40
   124
          return string.Format("{0:F0}", sensor.Value);
moel@40
   125
        case SensorType.Fan: 
moel@40
   126
          return string.Format("{0:F11}", 1e-3f * sensor.Value);
moel@40
   127
      }
moel@40
   128
      return "-";
moel@40
   129
    }
moel@40
   130
moel@40
   131
    private Icon CreateSimpleIcon() {
moel@40
   132
moel@40
   133
      graphics.Clear(SystemColors.ButtonFace);
moel@40
   134
      TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
moel@42
   135
        new Point(-2, 0), color, SystemColors.ButtonFace);
moel@40
   136
moel@40
   137
      BitmapData data = bitmap.LockBits(
moel@40
   138
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
moel@40
   139
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
moel@40
   140
moel@40
   141
      int stride = data.Stride;
moel@40
   142
      IntPtr Scan0 = data.Scan0;
moel@40
   143
moel@40
   144
      int numBytes = bitmap.Width * bitmap.Height * 4;
moel@40
   145
      byte[] bytes = new byte[numBytes];
moel@40
   146
      Marshal.Copy(Scan0, bytes, 0, numBytes);
moel@40
   147
      bitmap.UnlockBits(data);
moel@40
   148
moel@40
   149
      return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
moel@40
   150
    }
moel@40
   151
moel@40
   152
    private Icon CreateTransparentIcon() {
moel@40
   153
moel@40
   154
      graphics.Clear(Color.Black);
moel@40
   155
      TextRenderer.DrawText(graphics, GetString(), SystemFonts.StatusFont,
moel@40
   156
        new Point(-2, 0), Color.White, Color.Black);
moel@40
   157
moel@40
   158
      BitmapData data = bitmap.LockBits(
moel@40
   159
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
moel@40
   160
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
moel@40
   161
moel@40
   162
      int stride = data.Stride;
moel@40
   163
      IntPtr Scan0 = data.Scan0;
moel@40
   164
moel@40
   165
      int numBytes = bitmap.Width * bitmap.Height * 4;
moel@40
   166
      byte[] bytes = new byte[numBytes];
moel@40
   167
      Marshal.Copy(Scan0, bytes, 0, numBytes);
moel@40
   168
      bitmap.UnlockBits(data);
moel@40
   169
moel@40
   170
      byte red, green, blue;
moel@40
   171
      for (int i = 0; i < bytes.Length; i += 4) {
moel@40
   172
        blue = bytes[i];
moel@40
   173
        green = bytes[i + 1];
moel@40
   174
        red = bytes[i + 2];
moel@40
   175
moel@42
   176
        bytes[i] = color.B;
moel@42
   177
        bytes[i + 1] = color.G;
moel@42
   178
        bytes[i + 2] = color.R;
moel@40
   179
        bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
moel@40
   180
      }
moel@40
   181
moel@40
   182
      return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
moel@40
   183
    }
moel@40
   184
moel@40
   185
    public void Update() {
moel@40
   186
      Icon icon = notifyIcon.Icon;
moel@40
   187
moel@40
   188
      if (majorVersion < 6) {
moel@40
   189
        notifyIcon.Icon = CreateSimpleIcon();
moel@40
   190
      } else {
moel@40
   191
        notifyIcon.Icon = CreateTransparentIcon();
moel@40
   192
      }
moel@40
   193
      
moel@40
   194
      if (icon != null) 
moel@40
   195
        icon.Dispose();
moel@40
   196
moel@40
   197
      string format = "";
moel@40
   198
      switch (sensor.SensorType) {
moel@40
   199
        case SensorType.Voltage: format = "{0}\n{1}: {2:F2} V"; break;
moel@40
   200
        case SensorType.Clock: format = "{0}\n{1}: {2:F0} MHz"; break;
moel@40
   201
        case SensorType.Load: format = "{0}\n{1}: {2:F1} %"; break;
moel@40
   202
        case SensorType.Temperature: format = "{0}\n{1}: {2:F1} °C"; break;
moel@40
   203
        case SensorType.Fan: format = "{0}\n{1}: {2:F0} RPM"; break;
moel@40
   204
      }
moel@40
   205
moel@42
   206
      notifyIcon.Text = string.Format(format, sensor.Hardware.Name, sensor.Name,
moel@42
   207
        sensor.Value);    
moel@42
   208
      notifyIcon.Visible = true;         
moel@40
   209
    }
moel@40
   210
  }
moel@40
   211
}