Added a desktop gadget implementation.
authormoel.mich
Mon, 06 Sep 2010 19:53:13 +0000
changeset 176c16fd81b520a
parent 175 e4ee19d583bd
child 177 510f27ad65ac
Added a desktop gadget implementation.
GUI/Gadget.cs
GUI/GadgetWindow.cs
GUI/HardwareNode.cs
GUI/HardwareTypeImage.cs
GUI/MainForm.Designer.cs
GUI/MainForm.cs
GUI/SensorGadget.cs
GUI/SensorNotifyIcon.cs
GUI/ShowDesktop.cs
Hardware/ATI/ATIGPU.cs
Hardware/HDD/HDD.cs
Hardware/Hardware.cs
Hardware/IHardware.cs
Hardware/Identifier.cs
Hardware/Mainboard/Mainboard.cs
Hardware/Mainboard/SuperIOHardware.cs
Hardware/Nvidia/NvidiaGPU.cs
Hardware/TBalancer/TBalancer.cs
OpenHardwareMonitor.csproj
Properties/AssemblyVersion.cs
Resources/barback.png
Resources/barblue.png
Resources/gadget.png
Resources/gadget.xcf
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/GUI/Gadget.cs	Mon Sep 06 19:53:13 2010 +0000
     1.3 @@ -0,0 +1,172 @@
     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) 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.Drawing;
    1.43 +using System.Drawing.Drawing2D;
    1.44 +using System.Drawing.Imaging;
    1.45 +using System.Drawing.Text;
    1.46 +using System.Windows.Forms;
    1.47 +
    1.48 +namespace OpenHardwareMonitor.GUI {
    1.49 +  public abstract class Gadget : IDisposable {
    1.50 +
    1.51 +    private GadgetWindow window;
    1.52 +    private Bitmap buffer;
    1.53 +    private Graphics graphics;
    1.54 +
    1.55 +    public Gadget() {
    1.56 +      this.window = new GadgetWindow();
    1.57 +      CreateBuffer();
    1.58 +    }
    1.59 +
    1.60 +    public void Dispose() {
    1.61 +      this.graphics.Dispose();
    1.62 +      this.buffer.Dispose();
    1.63 +    }
    1.64 +
    1.65 +    public Point Location {
    1.66 +      get {
    1.67 +        return window.Location;
    1.68 +      }
    1.69 +      set {
    1.70 +        window.Location = value;
    1.71 +      }
    1.72 +    }
    1.73 +
    1.74 +    public event EventHandler LocationChanged {
    1.75 +      add {
    1.76 +        window.LocationChanged += value;
    1.77 +      }
    1.78 +      remove {
    1.79 +        window.LocationChanged -= value;
    1.80 +      }
    1.81 +    }
    1.82 +
    1.83 +    protected virtual Size Size {
    1.84 +      get {
    1.85 +        return window.Size; 
    1.86 +      }
    1.87 +      set {
    1.88 +        if (window.Size != value) {
    1.89 +          DisposeBuffer();
    1.90 +          this.window.Size = value;          
    1.91 +          CreateBuffer();
    1.92 +        }
    1.93 +      }
    1.94 +    }
    1.95 +
    1.96 +    public byte Opacity {
    1.97 +      get {
    1.98 +        return window.Opacity;
    1.99 +      }
   1.100 +      set {
   1.101 +        window.Opacity = value;
   1.102 +      }
   1.103 +    }
   1.104 +
   1.105 +    public bool LockPosition {
   1.106 +      get {
   1.107 +        return window.LockPosition;
   1.108 +      }
   1.109 +      set {
   1.110 +        window.LockPosition = value;
   1.111 +      }
   1.112 +    }
   1.113 +
   1.114 +    public bool AlwaysOnTop {
   1.115 +      get {
   1.116 +        return window.AlwaysOnTop;
   1.117 +      }
   1.118 +      set {
   1.119 +        window.AlwaysOnTop = value;
   1.120 +      }
   1.121 +    }
   1.122 +
   1.123 +    public ContextMenu ContextMenu {
   1.124 +      get {
   1.125 +        return window.ContextMenu;
   1.126 +      }
   1.127 +      set {
   1.128 +        window.ContextMenu = value;
   1.129 +      }
   1.130 +    }
   1.131 +
   1.132 +    private void CreateBuffer() {
   1.133 +      this.buffer = new Bitmap(window.Size.Width, window.Size.Height, 
   1.134 +        PixelFormat.Format32bppArgb);
   1.135 +      this.graphics = Graphics.FromImage(this.buffer);
   1.136 +      if (Environment.OSVersion.Version.Major > 5) {
   1.137 +        this.graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
   1.138 +        this.graphics.SmoothingMode = SmoothingMode.HighQuality;
   1.139 +      }
   1.140 +    }
   1.141 +
   1.142 +    private void DisposeBuffer() {
   1.143 +      if (buffer != null) {
   1.144 +        this.buffer.Dispose();
   1.145 +        this.buffer = null;
   1.146 +      }
   1.147 +      if (graphics != null) {
   1.148 +        this.graphics.Dispose();
   1.149 +        this.graphics = null;
   1.150 +      }
   1.151 +    }
   1.152 +
   1.153 +    public bool Visible {
   1.154 +      get {
   1.155 +        return window.Visible;
   1.156 +      }
   1.157 +      set {
   1.158 +        if (value != window.Visible) {
   1.159 +          if (value)
   1.160 +            Redraw();
   1.161 +          window.Visible = value;
   1.162 +        }
   1.163 +      }
   1.164 +    }
   1.165 +
   1.166 +    public void Redraw() {
   1.167 +      OnPaint(new PaintEventArgs(graphics, 
   1.168 +        new Rectangle(Point.Empty, window.Size)));
   1.169 +      window.Update(buffer);
   1.170 +    }
   1.171 +
   1.172 +    protected abstract void OnPaint(PaintEventArgs e);
   1.173 +  
   1.174 +  }
   1.175 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/GUI/GadgetWindow.cs	Mon Sep 06 19:53:13 2010 +0000
     2.3 @@ -0,0 +1,423 @@
     2.4 +/*
     2.5 +  
     2.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     2.7 +
     2.8 +  The contents of this file are subject to the Mozilla Public License Version
     2.9 +  1.1 (the "License"); you may not use this file except in compliance with
    2.10 +  the License. You may obtain a copy of the License at
    2.11 + 
    2.12 +  http://www.mozilla.org/MPL/
    2.13 +
    2.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    2.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    2.16 +  for the specific language governing rights and limitations under the License.
    2.17 +
    2.18 +  The Original Code is the Open Hardware Monitor code.
    2.19 +
    2.20 +  The Initial Developer of the Original Code is 
    2.21 +  Michael Möller <m.moeller@gmx.ch>.
    2.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    2.23 +  the Initial Developer. All Rights Reserved.
    2.24 +
    2.25 +  Contributor(s):
    2.26 +
    2.27 +  Alternatively, the contents of this file may be used under the terms of
    2.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    2.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    2.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    2.31 +  of those above. If you wish to allow use of your version of this file only
    2.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    2.33 +  use your version of this file under the terms of the MPL, indicate your
    2.34 +  decision by deleting the provisions above and replace them with the notice
    2.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    2.36 +  the provisions above, a recipient may use your version of this file under
    2.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    2.38 + 
    2.39 +*/
    2.40 +
    2.41 +using System;
    2.42 +using System.Drawing;
    2.43 +using System.Reflection;
    2.44 +using System.Runtime.InteropServices;
    2.45 +using System.Windows.Forms;
    2.46 +
    2.47 +namespace OpenHardwareMonitor.GUI {
    2.48 +  public class GadgetWindow : NativeWindow {
    2.49 +
    2.50 +    private bool visible = false;
    2.51 +    private bool lockPosition = false;
    2.52 +    private bool alwaysOnTop = false;
    2.53 +    private byte opacity = 255;
    2.54 +    private Point location = new Point(100, 100);
    2.55 +    private Size size = new Size(130, 84);
    2.56 +    private ContextMenu contextMenu = null;
    2.57 +    private MethodInfo commandDispatch;
    2.58 +
    2.59 +    public GadgetWindow() {
    2.60 +      Type commandType = 
    2.61 +        typeof(Form).Assembly.GetType("System.Windows.Forms.Command");
    2.62 +      commandDispatch = commandType.GetMethod("DispatchID", 
    2.63 +        BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, 
    2.64 +        null, new Type[]{ typeof(int) }, null);
    2.65 +
    2.66 +      this.CreateHandle(CreateParams);
    2.67 +
    2.68 +      // move window to the bottom
    2.69 +      MoveToBottom(Handle);
    2.70 +
    2.71 +      // prevent window from fading to a glass sheet when peek is invoked
    2.72 +      try {
    2.73 +        bool value = true;
    2.74 +        int r = NativeMethods.DwmSetWindowAttribute(Handle,
    2.75 +          WindowAttribute.DWMWA_EXCLUDED_FROM_PEEK, ref value,
    2.76 +          Marshal.SizeOf(value));
    2.77 +      } catch (DllNotFoundException) { } catch (EntryPointNotFoundException) { }
    2.78 +    }
    2.79 +
    2.80 +    private void ShowDesktopChanged(bool showDesktop) {
    2.81 +      if (showDesktop) {
    2.82 +        MoveToTopMost(Handle);
    2.83 +      } else {
    2.84 +        MoveToBottom(Handle);
    2.85 +      }
    2.86 +    }
    2.87 +
    2.88 +    private void MoveToBottom(IntPtr handle) {
    2.89 +      NativeMethods.SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0,
    2.90 +        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
    2.91 +    }
    2.92 +
    2.93 +    private void MoveToTopMost(IntPtr handle) {
    2.94 +      NativeMethods.SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0,
    2.95 +        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
    2.96 +    }
    2.97 +
    2.98 +    private void ShowContextMenu(Point position) {
    2.99 +      NativeMethods.TrackPopupMenuEx(contextMenu.Handle, 
   2.100 +        TPM_RIGHTBUTTON | TPM_VERTICAL, position.X,
   2.101 +        position.Y, Handle, IntPtr.Zero);
   2.102 +    }
   2.103 +
   2.104 +    protected virtual CreateParams CreateParams {
   2.105 +      get {
   2.106 +        CreateParams cp = new CreateParams();
   2.107 +        cp.Width = size.Width;
   2.108 +        cp.Height = size.Height;
   2.109 +        cp.X = location.X;
   2.110 +        cp.Y = location.Y;
   2.111 +        cp.ExStyle = WS_EX_LAYERED | WS_EX_TOOLWINDOW;
   2.112 +        return cp;
   2.113 +      }
   2.114 +    }
   2.115 +
   2.116 +    protected override void WndProc(ref Message message) {
   2.117 +      switch (message.Msg) {
   2.118 +        case WM_COMMAND:
   2.119 +          // need to dispatch the message for the context menu
   2.120 +          if (message.LParam == IntPtr.Zero) 
   2.121 +            commandDispatch.Invoke(null, new object[] { 
   2.122 +              message.WParam.ToInt32() & 0xFFFF });          
   2.123 +          break;
   2.124 +        case WM_NCHITTEST:           
   2.125 +          // all pixels of the form belong to the caption
   2.126 +          message.Result = HTCAPTION; 
   2.127 +          break;
   2.128 +        case WM_NCLBUTTONDBLCLK:  
   2.129 +          message.Result = IntPtr.Zero; break;
   2.130 +        case WM_NCRBUTTONDOWN:
   2.131 +          message.Result = IntPtr.Zero; break;
   2.132 +        case WM_NCRBUTTONUP:
   2.133 +          if (contextMenu != null)
   2.134 +            ShowContextMenu(new Point(
   2.135 +              (int)((uint)message.LParam & 0xFFFF), 
   2.136 +              (int)(((uint)message.LParam >>16) & 0xFFFF)));          
   2.137 +          message.Result = IntPtr.Zero; 
   2.138 +          break;
   2.139 +        case WM_WINDOWPOSCHANGING:         
   2.140 +          WindowPos wp = (WindowPos)Marshal.PtrToStructure(
   2.141 +            message.LParam, typeof(WindowPos));
   2.142 +
   2.143 +          // add the nomove flag if position is locked
   2.144 +          if (lockPosition)
   2.145 +            wp.flags |= SWP_NOMOVE;
   2.146 +
   2.147 +          // prevent the window from leaving the screen
   2.148 +          if ((wp.flags & SWP_NOMOVE) == 0) {            
   2.149 +            Rectangle rect = Screen.GetWorkingArea(new Point(wp.x, wp.y));
   2.150 +            const int margin = 20;
   2.151 +            wp.x = Math.Max(wp.x, rect.Left - wp.cx + margin);
   2.152 +            wp.x = Math.Min(wp.x, rect.Right - margin);
   2.153 +            wp.y = Math.Max(wp.y, rect.Top - wp.cy + margin);
   2.154 +            wp.y = Math.Min(wp.y, rect.Bottom - margin);
   2.155 +
   2.156 +            // raise the event if location changed
   2.157 +            if (location.X != wp.x || location.Y != wp.y) {
   2.158 +              location = new Point(wp.x, wp.y);
   2.159 +              if (LocationChanged != null)
   2.160 +                LocationChanged(this, EventArgs.Empty);
   2.161 +            }
   2.162 +          }          
   2.163 +
   2.164 +          Marshal.StructureToPtr(wp, message.LParam, false);
   2.165 +          message.Result = IntPtr.Zero;
   2.166 +          break;           
   2.167 +        default:
   2.168 +          base.WndProc(ref message); break;
   2.169 +      }      
   2.170 +    }
   2.171 +
   2.172 +    private BlendFunction CreateBlendFunction() {
   2.173 +      BlendFunction blend = new BlendFunction();
   2.174 +      blend.BlendOp = AC_SRC_OVER;
   2.175 +      blend.BlendFlags = 0;
   2.176 +      blend.SourceConstantAlpha = opacity;
   2.177 +      blend.AlphaFormat = AC_SRC_ALPHA;
   2.178 +      return blend;
   2.179 +    }
   2.180 +
   2.181 +    public void Update(Bitmap bitmap) {
   2.182 +      IntPtr screen = NativeMethods.GetDC(IntPtr.Zero);
   2.183 +      IntPtr memory = NativeMethods.CreateCompatibleDC(screen);
   2.184 +      IntPtr newHBitmap = IntPtr.Zero;
   2.185 +      IntPtr oldHBitmap = IntPtr.Zero;
   2.186 +
   2.187 +      try {
   2.188 +        newHBitmap = bitmap.GetHbitmap(Color.Black);
   2.189 +        oldHBitmap = NativeMethods.SelectObject(memory, newHBitmap);
   2.190 +
   2.191 +        Size size = bitmap.Size;
   2.192 +        Point pointSource = Point.Empty;
   2.193 +        Point topPos = Location;
   2.194 +
   2.195 +        BlendFunction blend = CreateBlendFunction();
   2.196 +        NativeMethods.UpdateLayeredWindow(Handle, screen, ref topPos,
   2.197 +          ref size, memory, ref pointSource, 0, ref blend, ULW_ALPHA);
   2.198 +      } finally {
   2.199 +        NativeMethods.ReleaseDC(IntPtr.Zero, screen);
   2.200 +        if (newHBitmap != IntPtr.Zero) {
   2.201 +          NativeMethods.SelectObject(memory, oldHBitmap);
   2.202 +          NativeMethods.DeleteObject(newHBitmap);
   2.203 +        }
   2.204 +        NativeMethods.DeleteDC(memory);
   2.205 +      }
   2.206 +    }
   2.207 +
   2.208 +    public byte Opacity {
   2.209 +      get {
   2.210 +        return opacity;
   2.211 +      }
   2.212 +      set {
   2.213 +        if (opacity != value) {
   2.214 +          opacity = value;
   2.215 +          BlendFunction blend = CreateBlendFunction();
   2.216 +          NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero, IntPtr.Zero,
   2.217 +            IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, ref blend, ULW_ALPHA);
   2.218 +        }
   2.219 +      }
   2.220 +    }
   2.221 +
   2.222 +    public bool Visible {
   2.223 +      get {
   2.224 +        return visible;
   2.225 +      }
   2.226 +      set {
   2.227 +        if (visible != value) {
   2.228 +          visible = value;
   2.229 +          NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 0, 0, 0, 0,
   2.230 +            SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER |
   2.231 +            (value ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
   2.232 +          if (value)
   2.233 +            ShowDesktop.Instance.ShowDesktopChanged += ShowDesktopChanged;
   2.234 +          else
   2.235 +            ShowDesktop.Instance.ShowDesktopChanged -= ShowDesktopChanged;         
   2.236 +        }
   2.237 +      }
   2.238 +    }
   2.239 +
   2.240 +    // if locked, the window can not be moved
   2.241 +    public bool LockPosition {
   2.242 +      get {
   2.243 +        return lockPosition;
   2.244 +      }
   2.245 +      set {
   2.246 +        lockPosition = value;
   2.247 +      }
   2.248 +    }
   2.249 +
   2.250 +    public bool AlwaysOnTop {
   2.251 +      get {
   2.252 +        return alwaysOnTop;
   2.253 +      }
   2.254 +      set {
   2.255 +        if (value != alwaysOnTop) {
   2.256 +          alwaysOnTop = value;
   2.257 +          if (alwaysOnTop) {
   2.258 +            ShowDesktop.Instance.ShowDesktopChanged -= ShowDesktopChanged;
   2.259 +            MoveToTopMost(Handle);            
   2.260 +          } else {
   2.261 +            MoveToBottom(Handle);
   2.262 +            ShowDesktop.Instance.ShowDesktopChanged += ShowDesktopChanged;
   2.263 +          }
   2.264 +        }
   2.265 +      }
   2.266 +    }
   2.267 +
   2.268 +    public Size Size {
   2.269 +      get {
   2.270 +        return size; 
   2.271 +      }
   2.272 +      set {
   2.273 +        if (size != value) {
   2.274 +          size = value;
   2.275 +          NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 0, 0, size.Width,
   2.276 +            size.Height, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | 
   2.277 +            SWP_NOSENDCHANGING);
   2.278 +        }
   2.279 +      }
   2.280 +    }
   2.281 +
   2.282 +    public Point Location {
   2.283 +      get {
   2.284 +        return location;
   2.285 +      }
   2.286 +      set {
   2.287 +        NativeMethods.SetWindowPos(Handle, IntPtr.Zero, value.X, value.Y, 0,
   2.288 +          0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING);
   2.289 +        location = value;
   2.290 +        if (LocationChanged != null)
   2.291 +          LocationChanged(this, EventArgs.Empty);
   2.292 +      }
   2.293 +    }
   2.294 +
   2.295 +    public event EventHandler LocationChanged;
   2.296 +
   2.297 +    public ContextMenu ContextMenu {
   2.298 +      get {
   2.299 +        return contextMenu;
   2.300 +      }
   2.301 +      set {
   2.302 +        this.contextMenu = value;
   2.303 +      }
   2.304 +    }
   2.305 +
   2.306 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   2.307 +    private struct BlendFunction {
   2.308 +      public byte BlendOp;
   2.309 +      public byte BlendFlags;
   2.310 +      public byte SourceConstantAlpha;
   2.311 +      public byte AlphaFormat;
   2.312 +    }
   2.313 +
   2.314 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   2.315 +    private struct WindowPos {
   2.316 +      public IntPtr hwnd;
   2.317 +      public IntPtr hwndInsertAfter;
   2.318 +      public int x;
   2.319 +      public int y;
   2.320 +      public int cx;
   2.321 +      public int cy;
   2.322 +      public uint flags;
   2.323 +    }
   2.324 +
   2.325 +    public static readonly IntPtr HWND_BOTTOM = (IntPtr)1;
   2.326 +    public static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
   2.327 +
   2.328 +    public const int WS_EX_LAYERED = 0x00080000;
   2.329 +    public const int WS_EX_TOOLWINDOW = 0x00000080;
   2.330 +
   2.331 +    public const uint SWP_NOSIZE = 0x0001;
   2.332 +    public const uint SWP_NOMOVE = 0x0002;
   2.333 +    public const uint SWP_NOACTIVATE = 0x0010;
   2.334 +    public const uint SWP_HIDEWINDOW = 0x0080;
   2.335 +    public const uint SWP_SHOWWINDOW = 0x0040;
   2.336 +    public const uint SWP_NOZORDER = 0x0004;
   2.337 +    public const uint SWP_NOSENDCHANGING = 0x0400;
   2.338 +
   2.339 +    public const int ULW_COLORKEY = 0x00000001;
   2.340 +    public const int ULW_ALPHA = 0x00000002;
   2.341 +    public const int ULW_OPAQUE = 0x00000004;
   2.342 +
   2.343 +    public const byte AC_SRC_OVER = 0x00;
   2.344 +    public const byte AC_SRC_ALPHA = 0x01;
   2.345 +
   2.346 +    public const int WM_NCHITTEST = 0x0084;
   2.347 +    public const int WM_NCLBUTTONDBLCLK = 0x00A3;
   2.348 +    public const int WM_NCLBUTTONDOWN = 0x00A1;
   2.349 +    public const int WM_NCLBUTTONUP = 0x00A2;
   2.350 +    public const int WM_NCRBUTTONDOWN = 0x00A4;
   2.351 +    public const int WM_NCRBUTTONUP = 0x00A5;
   2.352 +    public const int WM_WINDOWPOSCHANGING = 0x0046;
   2.353 +    public const int WM_COMMAND = 0x0111;
   2.354 +
   2.355 +    public const int TPM_RIGHTBUTTON = 0x0002;
   2.356 +    public const int TPM_VERTICAL = 0x0040;
   2.357 +
   2.358 +    public readonly IntPtr HTCAPTION = (IntPtr)2;
   2.359 +
   2.360 +    private enum WindowAttribute : int {
   2.361 +      DWMWA_NCRENDERING_ENABLED = 1,
   2.362 +      DWMWA_NCRENDERING_POLICY,
   2.363 +      DWMWA_TRANSITIONS_FORCEDISABLED,
   2.364 +      DWMWA_ALLOW_NCPAINT,
   2.365 +      DWMWA_CAPTION_BUTTON_BOUNDS,
   2.366 +      DWMWA_NONCLIENT_RTL_LAYOUT,
   2.367 +      DWMWA_FORCE_ICONIC_REPRESENTATION,
   2.368 +      DWMWA_FLIP3D_POLICY,
   2.369 +      DWMWA_EXTENDED_FRAME_BOUNDS,
   2.370 +      DWMWA_HAS_ICONIC_BITMAP,
   2.371 +      DWMWA_DISALLOW_PEEK,
   2.372 +      DWMWA_EXCLUDED_FROM_PEEK,
   2.373 +      DWMWA_LAST
   2.374 +    }
   2.375 +
   2.376 +    private static class NativeMethods {
   2.377 +      private const string USER = "user32.dll";
   2.378 +      private const string GDI = "gdi32.dll";
   2.379 +      public const string DWMAPI = "dwmapi.dll";
   2.380 +
   2.381 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.382 +      [return: MarshalAs(UnmanagedType.Bool)]
   2.383 +      public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, 
   2.384 +        ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, 
   2.385 +        int crKey, ref BlendFunction pblend, int dwFlags);
   2.386 +
   2.387 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.388 +      [return: MarshalAs(UnmanagedType.Bool)]
   2.389 +      public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,
   2.390 +        IntPtr pptDst, IntPtr psize, IntPtr hdcSrc, IntPtr pprSrc,
   2.391 +        int crKey, ref BlendFunction pblend, int dwFlags);  
   2.392 +
   2.393 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.394 +      public static extern IntPtr GetDC(IntPtr hWnd);
   2.395 +
   2.396 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.397 +      public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
   2.398 +
   2.399 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.400 +      public static extern bool SetWindowPos(IntPtr hWnd,
   2.401 +        IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
   2.402 +
   2.403 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   2.404 +      public static extern bool TrackPopupMenuEx(IntPtr hMenu, uint uFlags, 
   2.405 +        int x, int y, IntPtr hWnd, IntPtr tpmParams);
   2.406 +
   2.407 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.408 +      public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
   2.409 +
   2.410 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.411 +      [return: MarshalAs(UnmanagedType.Bool)]
   2.412 +      public static extern bool DeleteDC(IntPtr hdc);
   2.413 +      
   2.414 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.415 +      public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
   2.416 +
   2.417 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.418 +      [return: MarshalAs(UnmanagedType.Bool)]
   2.419 +      public static extern bool DeleteObject(IntPtr hObject);
   2.420 +
   2.421 +      [DllImport(DWMAPI, CallingConvention = CallingConvention.Winapi)]
   2.422 +      public static extern int DwmSetWindowAttribute(IntPtr hwnd,
   2.423 +        WindowAttribute dwAttribute, ref bool pvAttribute, int cbAttribute);
   2.424 +    }    
   2.425 +  }
   2.426 +}
     3.1 --- a/GUI/HardwareNode.cs	Tue Aug 24 22:11:10 2010 +0000
     3.2 +++ b/GUI/HardwareNode.cs	Mon Sep 06 19:53:13 2010 +0000
     3.3 @@ -55,32 +55,7 @@
     3.4        this.settings = settings;
     3.5        this.unitManager = unitManager;
     3.6        this.hardware = hardware;
     3.7 -      switch (hardware.HardwareType) {
     3.8 -        case HardwareType.CPU: 
     3.9 -          this.Image = Utilities.EmbeddedResources.GetImage("cpu.png");
    3.10 -          break;
    3.11 -        case HardwareType.GPU:
    3.12 -          if (hardware.Identifier.ToString().Contains("nvidia"))
    3.13 -            this.Image = Utilities.EmbeddedResources.GetImage("nvidia.png");
    3.14 -          else
    3.15 -            this.Image = Utilities.EmbeddedResources.GetImage("ati.png");
    3.16 -          break;
    3.17 -        case HardwareType.HDD: 
    3.18 -          this.Image = Utilities.EmbeddedResources.GetImage("hdd.png");
    3.19 -          break;
    3.20 -        case HardwareType.Heatmaster:
    3.21 -          this.Image = Utilities.EmbeddedResources.GetImage("bigng.png");
    3.22 -          break;
    3.23 -        case HardwareType.Mainboard: 
    3.24 -          this.Image = Utilities.EmbeddedResources.GetImage("mainboard.png");
    3.25 -          break;
    3.26 -        case HardwareType.SuperIO: 
    3.27 -          this.Image = Utilities.EmbeddedResources.GetImage("chip.png");
    3.28 -          break;
    3.29 -        case HardwareType.TBalancer: 
    3.30 -          this.Image = Utilities.EmbeddedResources.GetImage("bigng.png");
    3.31 -          break;
    3.32 -      }
    3.33 +      this.Image = HardwareTypeImage.Instance.GetImage(hardware.HardwareType);
    3.34  
    3.35        typeNodes.Add(new TypeNode(SensorType.Voltage));
    3.36        typeNodes.Add(new TypeNode(SensorType.Clock));      
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/GUI/HardwareTypeImage.cs	Mon Sep 06 19:53:13 2010 +0000
     4.3 @@ -0,0 +1,95 @@
     4.4 +/*
     4.5 +  
     4.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4.7 +
     4.8 +  The contents of this file are subject to the Mozilla Public License Version
     4.9 +  1.1 (the "License"); you may not use this file except in compliance with
    4.10 +  the License. You may obtain a copy of the License at
    4.11 + 
    4.12 +  http://www.mozilla.org/MPL/
    4.13 +
    4.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    4.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    4.16 +  for the specific language governing rights and limitations under the License.
    4.17 +
    4.18 +  The Original Code is the Open Hardware Monitor code.
    4.19 +
    4.20 +  The Initial Developer of the Original Code is 
    4.21 +  Michael Möller <m.moeller@gmx.ch>.
    4.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    4.23 +  the Initial Developer. All Rights Reserved.
    4.24 +
    4.25 +  Contributor(s):
    4.26 +
    4.27 +  Alternatively, the contents of this file may be used under the terms of
    4.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    4.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    4.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    4.31 +  of those above. If you wish to allow use of your version of this file only
    4.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    4.33 +  use your version of this file under the terms of the MPL, indicate your
    4.34 +  decision by deleting the provisions above and replace them with the notice
    4.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    4.36 +  the provisions above, a recipient may use your version of this file under
    4.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    4.38 + 
    4.39 +*/
    4.40 +
    4.41 +using System;
    4.42 +using System.Drawing;
    4.43 +using System.Collections.Generic;
    4.44 +using OpenHardwareMonitor.Hardware;
    4.45 +
    4.46 +namespace OpenHardwareMonitor.GUI {
    4.47 +  public class HardwareTypeImage {
    4.48 +    private static HardwareTypeImage instance = new HardwareTypeImage();
    4.49 +
    4.50 +    private IDictionary<HardwareType, Image> images = 
    4.51 +      new Dictionary<HardwareType, Image>();
    4.52 +
    4.53 +    private HardwareTypeImage() { }
    4.54 +
    4.55 +    public static HardwareTypeImage Instance {
    4.56 +      get { return instance; }
    4.57 +    }
    4.58 +
    4.59 +    public Image GetImage(HardwareType hardwareType) {
    4.60 +      Image image;
    4.61 +      if (images.TryGetValue(hardwareType, out image)) {
    4.62 +        return image;
    4.63 +      } else {
    4.64 +        switch (hardwareType) {
    4.65 +          case HardwareType.CPU:
    4.66 +            image = Utilities.EmbeddedResources.GetImage("cpu.png");
    4.67 +            break;
    4.68 +          case HardwareType.GpuNvidia:
    4.69 +            image = Utilities.EmbeddedResources.GetImage("nvidia.png");
    4.70 +            break;
    4.71 +          case HardwareType.GpuAti:
    4.72 +            image = Utilities.EmbeddedResources.GetImage("ati.png");
    4.73 +            break;
    4.74 +          case HardwareType.HDD:
    4.75 +            image = Utilities.EmbeddedResources.GetImage("hdd.png");
    4.76 +            break;
    4.77 +          case HardwareType.Heatmaster:
    4.78 +            image = Utilities.EmbeddedResources.GetImage("bigng.png");
    4.79 +            break;
    4.80 +          case HardwareType.Mainboard:
    4.81 +            image = Utilities.EmbeddedResources.GetImage("mainboard.png");
    4.82 +            break;
    4.83 +          case HardwareType.SuperIO:
    4.84 +            image = Utilities.EmbeddedResources.GetImage("chip.png");
    4.85 +            break;
    4.86 +          case HardwareType.TBalancer:
    4.87 +            image = Utilities.EmbeddedResources.GetImage("bigng.png");
    4.88 +            break;
    4.89 +          default:
    4.90 +            image = new Bitmap(1, 1);
    4.91 +            break;
    4.92 +        }
    4.93 +        images.Add(hardwareType, image);
    4.94 +        return image;
    4.95 +      }
    4.96 +    }
    4.97 +  }
    4.98 +}
     5.1 --- a/GUI/MainForm.Designer.cs	Tue Aug 24 22:11:10 2010 +0000
     5.2 +++ b/GUI/MainForm.Designer.cs	Mon Sep 06 19:53:13 2010 +0000
     5.3 @@ -88,6 +88,7 @@
     5.4        this.valueMenuItem = new System.Windows.Forms.MenuItem();
     5.5        this.minMenuItem = new System.Windows.Forms.MenuItem();
     5.6        this.maxMenuItem = new System.Windows.Forms.MenuItem();
     5.7 +      this.gadgetMenuItem = new System.Windows.Forms.MenuItem();
     5.8        this.optionsMenuItem = new System.Windows.Forms.MenuItem();
     5.9        this.startMinMenuItem = new System.Windows.Forms.MenuItem();
    5.10        this.minTrayMenuItem = new System.Windows.Forms.MenuItem();
    5.11 @@ -231,6 +232,7 @@
    5.12              this.MenuItem3,
    5.13              this.hiddenMenuItem,
    5.14              this.plotMenuItem,
    5.15 +            this.gadgetMenuItem,
    5.16              this.MenuItem1,
    5.17              this.columnsMenuItem});
    5.18        this.viewMenuItem.Text = "View";
    5.19 @@ -258,12 +260,12 @@
    5.20        // 
    5.21        // MenuItem1
    5.22        // 
    5.23 -      this.MenuItem1.Index = 4;
    5.24 +      this.MenuItem1.Index = 5;
    5.25        this.MenuItem1.Text = "-";
    5.26        // 
    5.27        // columnsMenuItem
    5.28        // 
    5.29 -      this.columnsMenuItem.Index = 5;
    5.30 +      this.columnsMenuItem.Index = 6;
    5.31        this.columnsMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    5.32              this.valueMenuItem,
    5.33              this.minMenuItem,
    5.34 @@ -285,6 +287,11 @@
    5.35        this.maxMenuItem.Index = 2;
    5.36        this.maxMenuItem.Text = "Max";
    5.37        // 
    5.38 +      // gadgetMenuItem
    5.39 +      // 
    5.40 +      this.gadgetMenuItem.Index = 4;
    5.41 +      this.gadgetMenuItem.Text = "Show Gadget";
    5.42 +      // 
    5.43        // optionsMenuItem
    5.44        // 
    5.45        this.optionsMenuItem.Index = 2;
    5.46 @@ -501,6 +508,7 @@
    5.47      private System.Windows.Forms.MenuItem MenuItem2;
    5.48      private System.Windows.Forms.MenuItem resetMinMaxMenuItem;
    5.49      private System.Windows.Forms.MenuItem MenuItem3;
    5.50 +    private System.Windows.Forms.MenuItem gadgetMenuItem;
    5.51    }
    5.52  }
    5.53  
     6.1 --- a/GUI/MainForm.cs	Tue Aug 24 22:11:10 2010 +0000
     6.2 +++ b/GUI/MainForm.cs	Mon Sep 06 19:53:13 2010 +0000
     6.3 @@ -62,6 +62,7 @@
     6.4      private SystemTray systemTray;    
     6.5      private StartupManager startupManager = new StartupManager();
     6.6      private UpdateVisitor updateVisitor = new UpdateVisitor();
     6.7 +    private SensorGadget gadget;
     6.8  
     6.9      private UserOption showHiddenSensors;
    6.10      private UserOption showPlot;
    6.11 @@ -72,6 +73,7 @@
    6.12      private UserOption minimizeToTray;
    6.13      private UserOption autoStart;
    6.14      private UserOption readHddSensors;
    6.15 +    private UserOption showGadget;
    6.16  
    6.17      public MainForm() {      
    6.18        InitializeComponent();
    6.19 @@ -138,6 +140,8 @@
    6.20        systemTray.HideShowCommand += hideShowClick;
    6.21        systemTray.ExitCommand += exitClick;
    6.22  
    6.23 +      gadget = new SensorGadget(computer, settings, unitManager);
    6.24 +
    6.25        computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
    6.26        computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
    6.27        computer.Open();
    6.28 @@ -194,7 +198,7 @@
    6.29  
    6.30        autoStart = new UserOption(null, startupManager.Startup, startupMenuItem, settings);
    6.31        autoStart.Changed += delegate(object sender, EventArgs e) {
    6.32 -        startupManager.Startup = autoStart.Value; ;
    6.33 +        startupManager.Startup = autoStart.Value; 
    6.34        };
    6.35  
    6.36        readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, settings);
    6.37 @@ -203,6 +207,11 @@
    6.38          UpdatePlotSelection(null, null);
    6.39        };
    6.40  
    6.41 +      showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, settings);
    6.42 +      showGadget.Changed += delegate(object sender, EventArgs e) {
    6.43 +        gadget.Visible = showGadget.Value;
    6.44 +      };
    6.45 +
    6.46        celciusMenuItem.Checked = 
    6.47          unitManager.TemperatureUnit == TemperatureUnit.Celcius;
    6.48        fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
    6.49 @@ -225,7 +234,7 @@
    6.50        Microsoft.Win32.SystemEvents.SessionEnded +=
    6.51          delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
    6.52            SaveConfiguration();
    6.53 -        };
    6.54 +        };  
    6.55      }
    6.56      
    6.57      private void SubHardwareAdded(IHardware hardware, Node node) {
    6.58 @@ -313,6 +322,7 @@
    6.59        treeView.Invalidate();
    6.60        plotPanel.Invalidate();
    6.61        systemTray.Redraw();
    6.62 +      gadget.Redraw();
    6.63      }
    6.64  
    6.65      private void SaveConfiguration() {
    6.66 @@ -369,7 +379,7 @@
    6.67                nodeTextBoxText.BeginEdit();
    6.68              };
    6.69              sensorContextMenu.MenuItems.Add(item);
    6.70 -          }          
    6.71 +          }
    6.72            if (node.IsVisible) {
    6.73              MenuItem item = new MenuItem("Hide");
    6.74              item.Click += delegate(object obj, EventArgs args) {
    6.75 @@ -382,20 +392,30 @@
    6.76                node.IsVisible = true;
    6.77              };
    6.78              sensorContextMenu.MenuItems.Add(item);
    6.79 -          }         
    6.80 -          if (systemTray.Contains(node.Sensor)) {
    6.81 -            MenuItem item = new MenuItem("Remove From Tray");
    6.82 -            item.Click += delegate(object obj, EventArgs args) {
    6.83 +          }
    6.84 +          sensorContextMenu.MenuItems.Add(new MenuItem("-"));
    6.85 +
    6.86 +          MenuItem menuItem = new MenuItem("Show in Tray");
    6.87 +          menuItem.Checked = systemTray.Contains(node.Sensor);
    6.88 +          menuItem.Click += delegate(object obj, EventArgs args) {
    6.89 +            if (menuItem.Checked)
    6.90                systemTray.Remove(node.Sensor);
    6.91 -            };
    6.92 -            sensorContextMenu.MenuItems.Add(item);
    6.93 -          } else {
    6.94 -            MenuItem item = new MenuItem("Add To Tray");
    6.95 -            item.Click += delegate(object obj, EventArgs args) {
    6.96 +            else
    6.97                systemTray.Add(node.Sensor, true);
    6.98 -            };
    6.99 -            sensorContextMenu.MenuItems.Add(item);
   6.100 -          }
   6.101 +          };
   6.102 +          sensorContextMenu.MenuItems.Add(menuItem);
   6.103 +
   6.104 +          menuItem = new MenuItem("Show in Gadget");
   6.105 +          menuItem.Checked = gadget.Contains(node.Sensor);
   6.106 +          menuItem.Click += delegate(object obj, EventArgs args) {
   6.107 +            if (menuItem.Checked) {
   6.108 +              gadget.Remove(node.Sensor);
   6.109 +            } else {
   6.110 +              gadget.Add(node.Sensor);
   6.111 +            }
   6.112 +          };
   6.113 +          sensorContextMenu.MenuItems.Add(menuItem);
   6.114 +
   6.115            sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   6.116          }
   6.117        }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/GUI/SensorGadget.cs	Mon Sep 06 19:53:13 2010 +0000
     7.3 @@ -0,0 +1,361 @@
     7.4 +/*
     7.5 +  
     7.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     7.7 +
     7.8 +  The contents of this file are subject to the Mozilla Public License Version
     7.9 +  1.1 (the "License"); you may not use this file except in compliance with
    7.10 +  the License. You may obtain a copy of the License at
    7.11 + 
    7.12 +  http://www.mozilla.org/MPL/
    7.13 +
    7.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    7.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    7.16 +  for the specific language governing rights and limitations under the License.
    7.17 +
    7.18 +  The Original Code is the Open Hardware Monitor code.
    7.19 +
    7.20 +  The Initial Developer of the Original Code is 
    7.21 +  Michael Möller <m.moeller@gmx.ch>.
    7.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    7.23 +  the Initial Developer. All Rights Reserved.
    7.24 +
    7.25 +  Contributor(s):
    7.26 +
    7.27 +  Alternatively, the contents of this file may be used under the terms of
    7.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    7.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    7.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    7.31 +  of those above. If you wish to allow use of your version of this file only
    7.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    7.33 +  use your version of this file under the terms of the MPL, indicate your
    7.34 +  decision by deleting the provisions above and replace them with the notice
    7.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    7.36 +  the provisions above, a recipient may use your version of this file under
    7.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    7.38 + 
    7.39 +*/
    7.40 +
    7.41 +using System;
    7.42 +using System.Collections.Generic;
    7.43 +using System.Drawing;
    7.44 +using System.Windows.Forms;
    7.45 +using OpenHardwareMonitor.Hardware;
    7.46 +
    7.47 +namespace OpenHardwareMonitor.GUI {
    7.48 +  public class SensorGadget : Gadget {
    7.49 +
    7.50 +    private UnitManager unitManager;
    7.51 +
    7.52 +    private Image back = Utilities.EmbeddedResources.GetImage("gadget.png");
    7.53 +    private Image barBack = Utilities.EmbeddedResources.GetImage("barback.png");
    7.54 +    private Image barblue = Utilities.EmbeddedResources.GetImage("barblue.png");
    7.55 +    private const int topBorder = 4;
    7.56 +    private const int bottomBorder = 6;
    7.57 +    private const int leftBorder = 6;
    7.58 +    private const int rightBorder = 6;
    7.59 +    private const int iconSize = 11;
    7.60 +    private const int hardwareLineHeight = 13;
    7.61 +    private const int sensorLineHeight = 11;
    7.62 +
    7.63 +    private IDictionary<IHardware, IList<ISensor>> sensors =
    7.64 +      new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
    7.65 +
    7.66 +    private PersistentSettings settings;
    7.67 +    private UserOption alwaysOnTop;
    7.68 +    private UserOption lockPosition;
    7.69 +
    7.70 +    private Font largeFont;
    7.71 +    private Font smallFont;
    7.72 +    private Brush darkWhite = new SolidBrush(Color.FromArgb(0xF0, 0xF0, 0xF0));
    7.73 +
    7.74 +    public SensorGadget(IComputer computer, PersistentSettings settings, 
    7.75 +      UnitManager unitManager) 
    7.76 +    {
    7.77 +      this.unitManager = unitManager;
    7.78 +      this.settings = settings;
    7.79 +      computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
    7.80 +      computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
    7.81 +
    7.82 +      this.largeFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 7.5f, 
    7.83 +        FontStyle.Bold); 
    7.84 +      this.smallFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 6.5f);      
    7.85 +
    7.86 +      this.Location = new Point(
    7.87 +        settings.GetValue("sensorGadget.Location.X", 100),
    7.88 +        settings.GetValue("sensorGadget.Location.Y", 100)); 
    7.89 +      LocationChanged += delegate(object sender, EventArgs e) {
    7.90 +        settings.SetValue("sensorGadget.Location.X", Location.X);
    7.91 +        settings.SetValue("sensorGadget.Location.Y", Location.Y);
    7.92 +      };
    7.93 +      
    7.94 +      ContextMenu contextMenu = new ContextMenu();
    7.95 +      MenuItem lockItem = new MenuItem("Lock Position");
    7.96 +      contextMenu.MenuItems.Add(lockItem);
    7.97 +      contextMenu.MenuItems.Add(new MenuItem("-"));
    7.98 +      MenuItem alwaysOnTopItem = new MenuItem("Always on Top");
    7.99 +      contextMenu.MenuItems.Add(alwaysOnTopItem);
   7.100 +      MenuItem opacityMenu = new MenuItem("Opacity");
   7.101 +      contextMenu.MenuItems.Add(opacityMenu);
   7.102 +      Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);      
   7.103 +      for (int i = 0; i < 5; i++) {
   7.104 +        MenuItem item = new MenuItem((20 * (i + 1)).ToString() + " %");
   7.105 +        byte o = (byte)(51 * (i + 1));
   7.106 +        item.Tag = o;
   7.107 +        item.Checked = Opacity == o;
   7.108 +        item.Click += delegate(object sender, EventArgs e) {
   7.109 +          Opacity = (byte)item.Tag;
   7.110 +          settings.SetValue("sensorGadget.Opacity", Opacity);
   7.111 +          foreach (MenuItem mi in opacityMenu.MenuItems)
   7.112 +            mi.Checked = (byte)mi.Tag == Opacity;          
   7.113 +        };
   7.114 +        opacityMenu.MenuItems.Add(item);
   7.115 +      }
   7.116 +      this.ContextMenu = contextMenu;
   7.117 +
   7.118 +      alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false, 
   7.119 +        alwaysOnTopItem, settings);
   7.120 +      alwaysOnTop.Changed += delegate(object sender, EventArgs e) {
   7.121 +        this.AlwaysOnTop = alwaysOnTop.Value;
   7.122 +      };
   7.123 +      lockPosition = new UserOption("sensorGadget.LockPosition", false,
   7.124 +        lockItem, settings);
   7.125 +      lockPosition.Changed += delegate(object sender, EventArgs e) {
   7.126 +        this.LockPosition = lockPosition.Value;
   7.127 +      };
   7.128 +
   7.129 +      Resize();
   7.130 +    }
   7.131 +
   7.132 +    private void HardwareRemoved(IHardware hardware) {
   7.133 +      hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
   7.134 +      hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
   7.135 +      foreach (ISensor sensor in hardware.Sensors)
   7.136 +        SensorRemoved(sensor);
   7.137 +      foreach (IHardware subHardware in hardware.SubHardware)
   7.138 +        HardwareRemoved(subHardware);
   7.139 +    }
   7.140 +
   7.141 +    private void HardwareAdded(IHardware hardware) {
   7.142 +      foreach (ISensor sensor in hardware.Sensors)
   7.143 +        SensorAdded(sensor);
   7.144 +      hardware.SensorAdded += new SensorEventHandler(SensorAdded);
   7.145 +      hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
   7.146 +      foreach (IHardware subHardware in hardware.SubHardware)
   7.147 +        HardwareAdded(subHardware);
   7.148 +    }
   7.149 +
   7.150 +    private void SensorAdded(ISensor sensor) {
   7.151 +      if (settings.GetValue(new Identifier(sensor.Identifier,
   7.152 +        "gadget").ToString(), false)) 
   7.153 +        Add(sensor);
   7.154 +    }
   7.155 +
   7.156 +    private void SensorRemoved(ISensor sensor) {
   7.157 +      if (Contains(sensor))
   7.158 +        Remove(sensor, false);
   7.159 +    }
   7.160 +
   7.161 +    public bool Contains(ISensor sensor) {
   7.162 +      foreach (IList<ISensor> list in sensors.Values)
   7.163 +        if (list.Contains(sensor))
   7.164 +          return true;
   7.165 +      return false;
   7.166 +    }
   7.167 +
   7.168 +    public void Add(ISensor sensor) {
   7.169 +      if (Contains(sensor)) {
   7.170 +        return;
   7.171 +      } else {
   7.172 +        // get the right hardware
   7.173 +        IHardware hardware = sensor.Hardware;
   7.174 +        while (hardware.Parent != null)
   7.175 +          hardware = hardware.Parent;
   7.176 +
   7.177 +        // get the sensor list associated with the hardware
   7.178 +        IList<ISensor> list;
   7.179 +        if (!sensors.TryGetValue(hardware, out list)) {
   7.180 +          list = new List<ISensor>();
   7.181 +          sensors.Add(hardware, list);
   7.182 +        }
   7.183 +
   7.184 +        // insert the sensor at the right position
   7.185 +        int i = 0;
   7.186 +        while (i < list.Count && (list[i].SensorType < sensor.SensorType || 
   7.187 +          (list[i].SensorType == sensor.SensorType && 
   7.188 +           list[i].Index < sensor.Index))) i++;
   7.189 +        list.Insert(i, sensor);
   7.190 +
   7.191 +        settings.SetValue(
   7.192 +          new Identifier(sensor.Identifier, "gadget").ToString(), true);
   7.193 +        
   7.194 +        Resize();
   7.195 +        Redraw();
   7.196 +      }
   7.197 +    }
   7.198 +
   7.199 +    public void Remove(ISensor sensor) {
   7.200 +      Remove(sensor, true);
   7.201 +    }
   7.202 +
   7.203 +    private void Remove(ISensor sensor, bool deleteConfig) {
   7.204 +      if (deleteConfig) 
   7.205 +        settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
   7.206 +
   7.207 +      foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in sensors)
   7.208 +        if (keyValue.Value.Contains(sensor)) {
   7.209 +          keyValue.Value.Remove(sensor);          
   7.210 +          if (keyValue.Value.Count == 0) {
   7.211 +            sensors.Remove(keyValue.Key);
   7.212 +            break;
   7.213 +          }
   7.214 +        }
   7.215 +      Resize();
   7.216 +      Redraw();
   7.217 +    }
   7.218 +
   7.219 +    private void Resize() {
   7.220 +      int y = topBorder + 1;
   7.221 +      foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
   7.222 +        y += hardwareLineHeight;
   7.223 +        y += pair.Value.Count * sensorLineHeight;
   7.224 +      }
   7.225 +      y += bottomBorder + 2;
   7.226 +      y = Math.Max(y, topBorder + bottomBorder + 10);
   7.227 +      this.Size = new Size(130, y);
   7.228 +    }
   7.229 +
   7.230 +    private void DrawBackground(Graphics g) {
   7.231 +      int w = Size.Width;
   7.232 +      int h = Size.Height;
   7.233 +      int t = topBorder;
   7.234 +      int b = bottomBorder;
   7.235 +      int l = leftBorder;
   7.236 +      int r = rightBorder;
   7.237 +      GraphicsUnit u = GraphicsUnit.Pixel;
   7.238 +
   7.239 +      g.DrawImage(back, new Rectangle(0, 0, l, t),
   7.240 +        new Rectangle(0, 0, l, t), u);
   7.241 +      g.DrawImage(back, new Rectangle(l, 0, w - l - r, t),
   7.242 +        new Rectangle(l, 0, back.Width - l - r, t), u);
   7.243 +      g.DrawImage(back, new Rectangle(w - r, 0, r, t),
   7.244 +        new Rectangle(back.Width - r, 0, r, t), u);
   7.245 +
   7.246 +      g.DrawImage(back, new Rectangle(0, t, l, h - t - b),
   7.247 +        new Rectangle(0, t, l, back.Height - t - b), u);
   7.248 +      g.DrawImage(back, new Rectangle(l, t, w - l - r, h - t - b),
   7.249 +        new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
   7.250 +      g.DrawImage(back, new Rectangle(w - r, t, r, h - t - b),
   7.251 +        new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
   7.252 +
   7.253 +      g.DrawImage(back, new Rectangle(0, h - b, l, b),
   7.254 +        new Rectangle(0, back.Height - b, l, b), u);
   7.255 +      g.DrawImage(back, new Rectangle(l, h - b, w - l - r, b),
   7.256 +        new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
   7.257 +      g.DrawImage(back, new Rectangle(w - r, h - b, r, b),
   7.258 +        new Rectangle(back.Width - r, back.Height - b, r, b), u);
   7.259 +    }
   7.260 +
   7.261 +    private void DrawProgress(Graphics g, int x, int y, int width, int height,
   7.262 +      float progress) 
   7.263 +    {
   7.264 +      g.DrawImage(barBack, 
   7.265 +        new RectangleF(x + width * progress, y, width * (1 - progress), height), 
   7.266 +        new RectangleF(barBack.Width * progress, 0, 
   7.267 +          (1 - progress) * barBack.Width, barBack.Height), 
   7.268 +        GraphicsUnit.Pixel);
   7.269 +      g.DrawImage(barblue,
   7.270 +        new RectangleF(x, y, width * progress, height),
   7.271 +        new RectangleF(0, 0, progress * barblue.Width, barblue.Height),
   7.272 +        GraphicsUnit.Pixel);
   7.273 +    }
   7.274 +
   7.275 +    protected override void OnPaint(PaintEventArgs e) {
   7.276 +      Graphics g = e.Graphics;
   7.277 +      int w = Size.Width;
   7.278 +      int h = Size.Height;
   7.279 +
   7.280 +      g.Clear(Color.Transparent);
   7.281 +
   7.282 +      DrawBackground(g);
   7.283 +
   7.284 +      StringFormat stringFormat = new StringFormat();
   7.285 +      stringFormat.Alignment = StringAlignment.Far;
   7.286 +
   7.287 +      int x;
   7.288 +      int y = topBorder + 1;
   7.289 +      foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
   7.290 +        x = leftBorder + 1;
   7.291 +        g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType),
   7.292 +          new Rectangle(x, y + 2, iconSize, iconSize));
   7.293 +        x += iconSize + 1;
   7.294 +        g.DrawString(pair.Key.Name, largeFont, Brushes.White,
   7.295 +          new Rectangle(x, y, w - rightBorder - x, 15));
   7.296 +        y += hardwareLineHeight;
   7.297 +
   7.298 +        foreach (ISensor sensor in pair.Value) {
   7.299 +
   7.300 +          g.DrawString(sensor.Name + ":", smallFont, darkWhite,
   7.301 +            new Rectangle(9, y, 64, 15));
   7.302 +          
   7.303 +          if (sensor.SensorType != SensorType.Load && 
   7.304 +            sensor.SensorType != SensorType.Control) 
   7.305 +          {
   7.306 +            string format = "";
   7.307 +            switch (sensor.SensorType) {
   7.308 +              case SensorType.Voltage:
   7.309 +                format = "{0:F2} V";
   7.310 +                break;
   7.311 +              case SensorType.Clock:
   7.312 +                format = "{0:F0} MHz";
   7.313 +                break;
   7.314 +              case SensorType.Temperature:
   7.315 +                format = "{0:F1} °C";
   7.316 +                break;
   7.317 +              case SensorType.Fan:
   7.318 +                format = "{0:F0} RPM";
   7.319 +                break;
   7.320 +              case SensorType.Flow:
   7.321 +                format = "{0:F0} L/h";
   7.322 +                break;
   7.323 +            }
   7.324 +
   7.325 +            string formattedValue;
   7.326 +            if (sensor.SensorType == SensorType.Temperature &&
   7.327 +              unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
   7.328 +              formattedValue = string.Format("{0:F1} °F",
   7.329 +                sensor.Value * 1.8 + 32);
   7.330 +            } else {
   7.331 +              formattedValue = string.Format(format, sensor.Value);
   7.332 +            }
   7.333 +
   7.334 +            x = 75;
   7.335 +            g.DrawString(formattedValue, smallFont, darkWhite,
   7.336 +              new RectangleF(x, y, w - x - 9, 15), stringFormat);            
   7.337 +          } else {
   7.338 +            x = 80;
   7.339 +            DrawProgress(g, x, y + 4, w - x - 9, 6, 0.01f * sensor.Value.Value);
   7.340 +          }
   7.341 +
   7.342 +          y += sensorLineHeight;
   7.343 +        }
   7.344 +      }
   7.345 +    }
   7.346 +
   7.347 +    private class HardwareComparer : IComparer<IHardware> {
   7.348 +      public int Compare(IHardware x, IHardware y) {
   7.349 +        if (x == null && y == null)
   7.350 +          return 0;
   7.351 +        if (x == null)
   7.352 +          return -1;
   7.353 +        if (y == null)
   7.354 +          return 1;
   7.355 +
   7.356 +        if (x.HardwareType != y.HardwareType)
   7.357 +          return x.HardwareType.CompareTo(y.HardwareType);
   7.358 +
   7.359 +        return x.Name.CompareTo(y.Name);
   7.360 +      }
   7.361 +    }
   7.362 +  }
   7.363 +}
   7.364 +
     8.1 --- a/GUI/SensorNotifyIcon.cs	Tue Aug 24 22:11:10 2010 +0000
     8.2 +++ b/GUI/SensorNotifyIcon.cs	Mon Sep 06 19:53:13 2010 +0000
     8.3 @@ -36,14 +36,12 @@
     8.4  */
     8.5  
     8.6  using System;
     8.7 -using System.Collections.Generic;
     8.8  using System.Drawing;
     8.9  using System.Drawing.Drawing2D;
    8.10  using System.Drawing.Imaging;
    8.11  using System.Drawing.Text;
    8.12 -using System.Text;
    8.13 +using System.Runtime.InteropServices;
    8.14  using System.Windows.Forms;
    8.15 -using System.Runtime.InteropServices;
    8.16  using OpenHardwareMonitor.Hardware;
    8.17  using OpenHardwareMonitor.Utilities;
    8.18  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/GUI/ShowDesktop.cs	Mon Sep 06 19:53:13 2010 +0000
     9.3 @@ -0,0 +1,172 @@
     9.4 +/*
     9.5 +  
     9.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     9.7 +
     9.8 +  The contents of this file are subject to the Mozilla Public License Version
     9.9 +  1.1 (the "License"); you may not use this file except in compliance with
    9.10 +  the License. You may obtain a copy of the License at
    9.11 + 
    9.12 +  http://www.mozilla.org/MPL/
    9.13 +
    9.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    9.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    9.16 +  for the specific language governing rights and limitations under the License.
    9.17 +
    9.18 +  The Original Code is the Open Hardware Monitor code.
    9.19 +
    9.20 +  The Initial Developer of the Original Code is 
    9.21 +  Michael Möller <m.moeller@gmx.ch>.
    9.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    9.23 +  the Initial Developer. All Rights Reserved.
    9.24 +
    9.25 +  Contributor(s):
    9.26 +
    9.27 +  Alternatively, the contents of this file may be used under the terms of
    9.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    9.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    9.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    9.31 +  of those above. If you wish to allow use of your version of this file only
    9.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    9.33 +  use your version of this file under the terms of the MPL, indicate your
    9.34 +  decision by deleting the provisions above and replace them with the notice
    9.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    9.36 +  the provisions above, a recipient may use your version of this file under
    9.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    9.38 + 
    9.39 +*/
    9.40 +
    9.41 +using System;
    9.42 +using System.Runtime.InteropServices;
    9.43 +using System.Windows.Forms;
    9.44 +
    9.45 +namespace OpenHardwareMonitor.GUI {
    9.46 +  public class ShowDesktop {
    9.47 +    private static ShowDesktop instance = new ShowDesktop();
    9.48 +
    9.49 +    public delegate void ShowDesktopChangedEventHandler(bool showDesktop);
    9.50 +    
    9.51 +    private event ShowDesktopChangedEventHandler ShowDesktopChangedEvent;
    9.52 +
    9.53 +    private System.Threading.Timer timer;
    9.54 +    private bool showDesktop = false;   
    9.55 +    private NativeWindow referenceWindow;
    9.56 +    private string referenceWindowCaption =
    9.57 +      "OpenHardwareMonitorShowDesktopReferenceWindow";
    9.58 +
    9.59 +    private ShowDesktop() {
    9.60 +      // create a reference window to detect show desktop
    9.61 +      referenceWindow = new NativeWindow();
    9.62 +      CreateParams cp = new CreateParams();
    9.63 +      cp.ExStyle = GadgetWindow.WS_EX_TOOLWINDOW;
    9.64 +      cp.Caption = referenceWindowCaption;
    9.65 +      referenceWindow.CreateHandle(cp);
    9.66 +      NativeMethods.SetWindowPos(referenceWindow.Handle, 
    9.67 +        GadgetWindow.HWND_BOTTOM, 0, 0, 0, 0, GadgetWindow.SWP_NOMOVE | 
    9.68 +        GadgetWindow.SWP_NOSIZE | GadgetWindow.SWP_NOACTIVATE | 
    9.69 +        GadgetWindow.SWP_NOSENDCHANGING);
    9.70 +
    9.71 +      // start a repeated timer to detect "Show Desktop" events 
    9.72 +      timer = new System.Threading.Timer(OnTimer, null,
    9.73 +        System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
    9.74 +    }
    9.75 +
    9.76 +    private void StartTimer() {
    9.77 +      timer.Change(0, 200);
    9.78 +    }
    9.79 +
    9.80 +    private void StopTimer() {
    9.81 +      timer.Change(System.Threading.Timeout.Infinite,
    9.82 +        System.Threading.Timeout.Infinite);
    9.83 +    }
    9.84 +
    9.85 +    // the desktop worker window (if available) can hide the reference window
    9.86 +    private IntPtr GetDesktopWorkerWindow() {
    9.87 +      IntPtr shellWindow = NativeMethods.GetShellWindow();
    9.88 +      if (shellWindow == IntPtr.Zero)
    9.89 +        return IntPtr.Zero;
    9.90 +
    9.91 +      int shellId;
    9.92 +      NativeMethods.GetWindowThreadProcessId(shellWindow, out shellId);
    9.93 +
    9.94 +      IntPtr workerWindow = IntPtr.Zero;
    9.95 +      while ((workerWindow = NativeMethods.FindWindowEx(
    9.96 +          IntPtr.Zero, workerWindow, "WorkerW", null)) != IntPtr.Zero) {
    9.97 +
    9.98 +        int workerId;
    9.99 +        NativeMethods.GetWindowThreadProcessId(workerWindow, out workerId);
   9.100 +        if (workerId == shellId) {
   9.101 +          IntPtr window = NativeMethods.FindWindowEx(
   9.102 +            workerWindow, IntPtr.Zero, "SHELLDLL_DefView", null);
   9.103 +          if (window != IntPtr.Zero) {
   9.104 +            IntPtr desktopWindow = NativeMethods.FindWindowEx(
   9.105 +              window, IntPtr.Zero, "SysListView32", null);
   9.106 +            if (desktopWindow != IntPtr.Zero)
   9.107 +              return workerWindow;
   9.108 +          }
   9.109 +        }
   9.110 +      }
   9.111 +      return IntPtr.Zero;
   9.112 +    }
   9.113 +
   9.114 +    private void OnTimer(Object state) {
   9.115 +      bool showDesktopDetected;
   9.116 +
   9.117 +      IntPtr workerWindow = GetDesktopWorkerWindow();
   9.118 +      if (workerWindow != IntPtr.Zero) {
   9.119 +        // search if the reference window is behind the worker window
   9.120 +        IntPtr reference = NativeMethods.FindWindowEx(
   9.121 +          IntPtr.Zero, workerWindow, null, referenceWindowCaption);
   9.122 +        showDesktopDetected = reference == referenceWindow.Handle;
   9.123 +      } else {
   9.124 +        // if there is no worker window, then nothing can hide the reference
   9.125 +        showDesktopDetected = false;
   9.126 +      }
   9.127 +
   9.128 +      if (showDesktop != showDesktopDetected) {
   9.129 +        showDesktop = showDesktopDetected;
   9.130 +        if (ShowDesktopChangedEvent != null) {
   9.131 +          ShowDesktopChangedEvent(showDesktop);
   9.132 +        }
   9.133 +      }
   9.134 +    }
   9.135 +
   9.136 +    public static ShowDesktop Instance {
   9.137 +      get { return instance; }
   9.138 +    }
   9.139 +
   9.140 +    // notify when the "show desktop" mode is changed
   9.141 +    public event ShowDesktopChangedEventHandler ShowDesktopChanged {
   9.142 +      add {
   9.143 +        // start the monitor timer when someone is listening
   9.144 +        if (ShowDesktopChangedEvent == null)           
   9.145 +          StartTimer();
   9.146 +        ShowDesktopChangedEvent += value;
   9.147 +      }
   9.148 +      remove {
   9.149 +        ShowDesktopChangedEvent -= value;
   9.150 +        // stop the monitor timer if nobody is interested
   9.151 +        if (ShowDesktopChangedEvent == null)
   9.152 +          StopTimer();
   9.153 +      }
   9.154 +    }
   9.155 +
   9.156 +    private static class NativeMethods {
   9.157 +      private const string USER = "user32.dll";
   9.158 +
   9.159 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   9.160 +      public static extern bool SetWindowPos(IntPtr hWnd,
   9.161 +        IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
   9.162 +
   9.163 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   9.164 +      public static extern IntPtr FindWindowEx(IntPtr hwndParent,
   9.165 +        IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
   9.166 +
   9.167 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   9.168 +      public static extern IntPtr GetShellWindow();
   9.169 +
   9.170 +      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
   9.171 +      public static extern int GetWindowThreadProcessId(IntPtr hWnd,
   9.172 +        out int processId);
   9.173 +    }  
   9.174 +  }
   9.175 +}
    10.1 --- a/Hardware/ATI/ATIGPU.cs	Tue Aug 24 22:11:10 2010 +0000
    10.2 +++ b/Hardware/ATI/ATIGPU.cs	Mon Sep 06 19:53:13 2010 +0000
    10.3 @@ -88,7 +88,7 @@
    10.4      }
    10.5  
    10.6      public override HardwareType HardwareType {
    10.7 -      get { return HardwareType.GPU; }
    10.8 +      get { return HardwareType.GpuAti; }
    10.9      }
   10.10  
   10.11      public override void Update() {
    11.1 --- a/Hardware/HDD/HDD.cs	Tue Aug 24 22:11:10 2010 +0000
    11.2 +++ b/Hardware/HDD/HDD.cs	Mon Sep 06 19:53:13 2010 +0000
    11.3 @@ -85,6 +85,10 @@
    11.4        get { return new IHardware[0]; }
    11.5      }
    11.6  
    11.7 +    public virtual IHardware Parent {
    11.8 +      get { return null; }
    11.9 +    }
   11.10 +
   11.11      public ISensor[] Sensors {
   11.12        get {
   11.13          return new ISensor[] { temperature };
    12.1 --- a/Hardware/Hardware.cs	Tue Aug 24 22:11:10 2010 +0000
    12.2 +++ b/Hardware/Hardware.cs	Mon Sep 06 19:53:13 2010 +0000
    12.3 @@ -48,6 +48,10 @@
    12.4        get { return new IHardware[0]; }
    12.5      }
    12.6  
    12.7 +    public virtual IHardware Parent {
    12.8 +      get { return null; }
    12.9 +    }
   12.10 +
   12.11      public ISensor[] Sensors {
   12.12        get { return active.ToArray(); }
   12.13      }
    13.1 --- a/Hardware/IHardware.cs	Tue Aug 24 22:11:10 2010 +0000
    13.2 +++ b/Hardware/IHardware.cs	Mon Sep 06 19:53:13 2010 +0000
    13.3 @@ -42,14 +42,15 @@
    13.4  
    13.5    public delegate void SensorEventHandler(ISensor sensor);
    13.6  
    13.7 -  public enum HardwareType {    
    13.8 -    CPU,
    13.9 -    GPU,
   13.10 -    HDD,
   13.11 -    Heatmaster,
   13.12 +  public enum HardwareType {
   13.13      Mainboard,
   13.14      SuperIO,
   13.15 -    TBalancer
   13.16 +    CPU,
   13.17 +    GpuNvidia,
   13.18 +    GpuAti,    
   13.19 +    TBalancer,
   13.20 +    Heatmaster,
   13.21 +    HDD,     
   13.22    }
   13.23  
   13.24    public interface IHardware : IElement {
   13.25 @@ -65,6 +66,8 @@
   13.26  
   13.27      IHardware[] SubHardware { get; }
   13.28  
   13.29 +    IHardware Parent { get; }
   13.30 +
   13.31      ISensor[] Sensors { get; }
   13.32  
   13.33      event SensorEventHandler SensorAdded;
    14.1 --- a/Hardware/Identifier.cs	Tue Aug 24 22:11:10 2010 +0000
    14.2 +++ b/Hardware/Identifier.cs	Mon Sep 06 19:53:13 2010 +0000
    14.3 @@ -40,7 +40,7 @@
    14.4  using System.Text;
    14.5  
    14.6  namespace OpenHardwareMonitor.Hardware {
    14.7 -  public class Identifier {
    14.8 +  public class Identifier : IComparable<Identifier> {
    14.9      private string identifier;
   14.10  
   14.11      private static char SEPARATOR = '/';
   14.12 @@ -92,5 +92,12 @@
   14.13      public override int GetHashCode() {
   14.14        return identifier.GetHashCode();
   14.15      }
   14.16 +
   14.17 +    public int CompareTo(Identifier other) {
   14.18 +      if (other == null)
   14.19 +        return 1;
   14.20 +      else 
   14.21 +        return this.identifier.CompareTo(other.identifier);
   14.22 +    }
   14.23    }
   14.24  }
    15.1 --- a/Hardware/Mainboard/Mainboard.cs	Tue Aug 24 22:11:10 2010 +0000
    15.2 +++ b/Hardware/Mainboard/Mainboard.cs	Mon Sep 06 19:53:13 2010 +0000
    15.3 @@ -78,7 +78,7 @@
    15.4        
    15.5        superIOHardware = new IHardware[superIO.Length];
    15.6        for (int i = 0; i < superIO.Length; i++)
    15.7 -        superIOHardware[i] = new SuperIOHardware(superIO[i], 
    15.8 +        superIOHardware[i] = new SuperIOHardware(this, superIO[i], 
    15.9            smbios.Board != null ? smbios.Board.Manufacturer : 
   15.10            Manufacturer.Unknown, smbios.Board != null ? smbios.Board.Model :
   15.11            Model.Unknown, settings);
   15.12 @@ -96,6 +96,10 @@
   15.13        get { return HardwareType.Mainboard; }
   15.14      }
   15.15  
   15.16 +    public virtual IHardware Parent {
   15.17 +      get { return null; }
   15.18 +    }
   15.19 +
   15.20      public string GetReport() {
   15.21        StringBuilder r = new StringBuilder(); 
   15.22  
    16.1 --- a/Hardware/Mainboard/SuperIOHardware.cs	Tue Aug 24 22:11:10 2010 +0000
    16.2 +++ b/Hardware/Mainboard/SuperIOHardware.cs	Mon Sep 06 19:53:13 2010 +0000
    16.3 @@ -43,6 +43,7 @@
    16.4  namespace OpenHardwareMonitor.Hardware.Mainboard {
    16.5    internal class SuperIOHardware : Hardware {
    16.6  
    16.7 +    private Mainboard mainboard;
    16.8      private ISuperIO superIO;
    16.9      private string name;
   16.10  
   16.11 @@ -51,9 +52,10 @@
   16.12      private List<Sensor> fans = new List<Sensor>();
   16.13  
   16.14  
   16.15 -    public SuperIOHardware(ISuperIO superIO, Manufacturer manufacturer,
   16.16 -      Model model, ISettings settings) 
   16.17 +    public SuperIOHardware(Mainboard mainboard, ISuperIO superIO, 
   16.18 +      Manufacturer manufacturer, Model model, ISettings settings) 
   16.19      {
   16.20 +      this.mainboard = mainboard;
   16.21        this.superIO = superIO;
   16.22        this.name = ChipName.GetName(superIO.Chip);
   16.23  
   16.24 @@ -614,6 +616,10 @@
   16.25        get { return HardwareType.SuperIO; }
   16.26      }
   16.27  
   16.28 +    public override IHardware Parent {
   16.29 +      get { return mainboard; }
   16.30 +    }
   16.31 +
   16.32      public override string Name {
   16.33        get { return name; }
   16.34      }
    17.1 --- a/Hardware/Nvidia/NvidiaGPU.cs	Tue Aug 24 22:11:10 2010 +0000
    17.2 +++ b/Hardware/Nvidia/NvidiaGPU.cs	Mon Sep 06 19:53:13 2010 +0000
    17.3 @@ -123,7 +123,7 @@
    17.4      }
    17.5  
    17.6      public override HardwareType HardwareType {
    17.7 -      get { return HardwareType.GPU; }
    17.8 +      get { return HardwareType.GpuNvidia; }
    17.9      }
   17.10  
   17.11      private NvGPUThermalSettings GetThermalSettings() {
    18.1 --- a/Hardware/TBalancer/TBalancer.cs	Tue Aug 24 22:11:10 2010 +0000
    18.2 +++ b/Hardware/TBalancer/TBalancer.cs	Mon Sep 06 19:53:13 2010 +0000
    18.3 @@ -285,6 +285,10 @@
    18.4        get { return new IHardware[0]; }
    18.5      }
    18.6  
    18.7 +    public virtual IHardware Parent {
    18.8 +      get { return null; }
    18.9 +    }
   18.10 +
   18.11      public ISensor[] Sensors {
   18.12        get { return active.ToArray(); }
   18.13      }
    19.1 --- a/OpenHardwareMonitor.csproj	Tue Aug 24 22:11:10 2010 +0000
    19.2 +++ b/OpenHardwareMonitor.csproj	Mon Sep 06 19:53:13 2010 +0000
    19.3 @@ -70,6 +70,9 @@
    19.4      </Reference>
    19.5    </ItemGroup>
    19.6    <ItemGroup>
    19.7 +    <Compile Include="GUI\GadgetWindow.cs" />
    19.8 +    <Compile Include="GUI\Gadget.cs" />
    19.9 +    <Compile Include="GUI\HardwareTypeImage.cs" />
   19.10      <Compile Include="GUI\PlotPanel.cs">
   19.11        <SubType>UserControl</SubType>
   19.12      </Compile>
   19.13 @@ -92,7 +95,9 @@
   19.14      <Compile Include="GUI\ParameterForm.Designer.cs">
   19.15        <DependentUpon>ParameterForm.cs</DependentUpon>
   19.16      </Compile>
   19.17 +    <Compile Include="GUI\SensorGadget.cs" />
   19.18      <Compile Include="GUI\SensorNotifyIcon.cs" />
   19.19 +    <Compile Include="GUI\ShowDesktop.cs" />
   19.20      <Compile Include="GUI\SplitContainerAdv.cs">
   19.21        <SubType>Component</SubType>
   19.22      </Compile>
   19.23 @@ -197,6 +202,11 @@
   19.24        <Install>true</Install>
   19.25      </BootstrapperPackage>
   19.26    </ItemGroup>
   19.27 +  <ItemGroup>
   19.28 +    <EmbeddedResource Include="Resources\barback.png" />
   19.29 +    <EmbeddedResource Include="Resources\barblue.png" />
   19.30 +    <EmbeddedResource Include="Resources\gadget.png" />
   19.31 +  </ItemGroup>
   19.32    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   19.33    <ProjectExtensions>
   19.34      <VisualStudio AllowExistingFolder="true" />
    20.1 --- a/Properties/AssemblyVersion.cs	Tue Aug 24 22:11:10 2010 +0000
    20.2 +++ b/Properties/AssemblyVersion.cs	Mon Sep 06 19:53:13 2010 +0000
    20.3 @@ -38,5 +38,5 @@
    20.4  using System;
    20.5  using System.Reflection;
    20.6  
    20.7 -[assembly: AssemblyVersion("0.1.37.9")]
    20.8 -[assembly: AssemblyFileVersion("0.1.37.9")]
    20.9 +[assembly: AssemblyVersion("0.1.37.10")]
   20.10 +[assembly: AssemblyFileVersion("0.1.37.10")]
    21.1 Binary file Resources/barback.png has changed
    22.1 Binary file Resources/barblue.png has changed
    23.1 Binary file Resources/gadget.png has changed
    24.1 Binary file Resources/gadget.xcf has changed