GUI/GadgetWindow.cs
changeset 302 44c0e7f76e9e
parent 244 99f16e21cdc8
child 344 3145aadca3d2
     1.1 --- a/GUI/GadgetWindow.cs	Sun Jun 19 14:14:00 2011 +0000
     1.2 +++ b/GUI/GadgetWindow.cs	Wed Jun 22 22:36:17 2011 +0000
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5    The Initial Developer of the Original Code is 
     1.6    Michael Möller <m.moeller@gmx.ch>.
     1.7 -  Portions created by the Initial Developer are Copyright (C) 2010
     1.8 +  Portions created by the Initial Developer are Copyright (C) 2010-2011
     1.9    the Initial Developer. All Rights Reserved.
    1.10  
    1.11    Contributor(s):
    1.12 @@ -37,13 +37,15 @@
    1.13  
    1.14  using System;
    1.15  using System.Drawing;
    1.16 +using System.Drawing.Drawing2D;
    1.17 +using System.Drawing.Text;
    1.18  using System.Reflection;
    1.19  using System.Runtime.InteropServices;
    1.20  using System.Windows.Forms;
    1.21  
    1.22  namespace OpenHardwareMonitor.GUI {
    1.23  
    1.24 -  public class GadgetWindow : NativeWindow {
    1.25 +  public class GadgetWindow : NativeWindow, IDisposable {
    1.26  
    1.27      private bool visible = false;
    1.28      private bool lockPositionAndSize = false;
    1.29 @@ -53,6 +55,9 @@
    1.30      private Size size = new Size(130, 84);
    1.31      private ContextMenu contextMenu = null;
    1.32      private MethodInfo commandDispatch;
    1.33 +    private IntPtr handleBitmapDC;
    1.34 +    private Size bufferSize;
    1.35 +    private Graphics graphics;
    1.36  
    1.37      public GadgetWindow() {
    1.38        Type commandType = 
    1.39 @@ -73,6 +78,8 @@
    1.40            WindowAttribute.DWMWA_EXCLUDED_FROM_PEEK, ref value,
    1.41            Marshal.SizeOf(value));
    1.42        } catch (DllNotFoundException) { } catch (EntryPointNotFoundException) { }
    1.43 +
    1.44 +      CreateBuffer();
    1.45      }
    1.46  
    1.47      private void ShowDesktopChanged(bool showDesktop) {
    1.48 @@ -223,35 +230,66 @@
    1.49        return blend;
    1.50      }
    1.51  
    1.52 -    public void Update(Bitmap bitmap) {
    1.53 -      IntPtr screen = NativeMethods.GetDC(IntPtr.Zero);
    1.54 -      IntPtr memory = NativeMethods.CreateCompatibleDC(screen);
    1.55 -      IntPtr newHBitmap = IntPtr.Zero;
    1.56 -      IntPtr oldHBitmap = IntPtr.Zero;
    1.57 +    private void CreateBuffer() {      
    1.58 +      IntPtr handleScreenDC = NativeMethods.GetDC(IntPtr.Zero);
    1.59 +      handleBitmapDC = NativeMethods.CreateCompatibleDC(handleScreenDC);
    1.60 +      NativeMethods.ReleaseDC(IntPtr.Zero, handleScreenDC);
    1.61 +      bufferSize = size;
    1.62  
    1.63 -      try {
    1.64 -        newHBitmap = bitmap.GetHbitmap(Color.Black);
    1.65 -        oldHBitmap = NativeMethods.SelectObject(memory, newHBitmap);
    1.66 +      BitmapInfo info = new BitmapInfo();
    1.67 +      info.Size = Marshal.SizeOf(info);
    1.68 +      info.Width = size.Width;
    1.69 +      info.Height = -size.Height;
    1.70 +      info.BitCount = 32;
    1.71 +      info.Planes = 1;
    1.72 +
    1.73 +      IntPtr ptr;
    1.74 +      IntPtr hBmp = NativeMethods.CreateDIBSection(handleBitmapDC, ref info, 0, 
    1.75 +        out ptr, IntPtr.Zero, 0);
    1.76 +      IntPtr hBmpOld = NativeMethods.SelectObject(handleBitmapDC, hBmp);
    1.77 +      NativeMethods.DeleteObject(hBmpOld);
    1.78 +      
    1.79 +      graphics = Graphics.FromHdc(handleBitmapDC);
    1.80 +
    1.81 +      if (Environment.OSVersion.Version.Major > 5) {
    1.82 +        this.graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
    1.83 +        this.graphics.SmoothingMode = SmoothingMode.HighQuality;
    1.84 +      } 
    1.85 +    }
    1.86 +
    1.87 +    private void DisposeBuffer() {
    1.88 +      graphics.Dispose();
    1.89 +      NativeMethods.DeleteDC(handleBitmapDC);
    1.90 +    }
    1.91 +
    1.92 +    public virtual void Dispose() {
    1.93 +      DisposeBuffer();
    1.94 +    } 
    1.95 +
    1.96 +    public PaintEventHandler Paint; 
    1.97 +
    1.98 +    public void Redraw() {
    1.99 +      if (!visible || Paint == null)
   1.100 +        return;
   1.101 +
   1.102 +      if (size != bufferSize) {
   1.103 +        DisposeBuffer();
   1.104 +        CreateBuffer();
   1.105 +      }
   1.106 +
   1.107 +      Paint(this, 
   1.108 +        new PaintEventArgs(graphics, new Rectangle(Point.Empty, size))); 
   1.109  
   1.110          Point pointSource = Point.Empty;
   1.111          BlendFunction blend = CreateBlendFunction();
   1.112  
   1.113 -        NativeMethods.UpdateLayeredWindow(Handle, screen, IntPtr.Zero,
   1.114 -          ref size, memory, ref pointSource, 0, ref blend, ULW_ALPHA);
   1.115 +        NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero, IntPtr.Zero,
   1.116 +          ref size, handleBitmapDC, ref pointSource, 0, ref blend, ULW_ALPHA);
   1.117  
   1.118          // make sure the window is at the right location
   1.119 -        NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 
   1.120 -          location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | 
   1.121 +        NativeMethods.SetWindowPos(Handle, IntPtr.Zero,
   1.122 +          location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE |
   1.123            SWP_NOZORDER | SWP_NOSENDCHANGING);
   1.124 -
   1.125 -      } finally {        
   1.126 -        if (newHBitmap != IntPtr.Zero) {
   1.127 -          NativeMethods.SelectObject(memory, oldHBitmap);
   1.128 -          NativeMethods.DeleteObject(newHBitmap);
   1.129 -        }
   1.130 -        NativeMethods.DeleteDC(memory);
   1.131 -        NativeMethods.ReleaseDC(IntPtr.Zero, screen);
   1.132 -      }
   1.133      }
   1.134  
   1.135      public byte Opacity {
   1.136 @@ -386,6 +424,22 @@
   1.137        public uint flags;
   1.138      }
   1.139  
   1.140 +    [StructLayout(LayoutKind.Sequential)]
   1.141 +    public struct BitmapInfo {
   1.142 +      public Int32 Size;
   1.143 +      public Int32 Width;
   1.144 +      public Int32 Height;
   1.145 +      public Int16 Planes;
   1.146 +      public Int16 BitCount;
   1.147 +      public Int32 Compression;
   1.148 +      public Int32 SizeImage;
   1.149 +      public Int32 XPelsPerMeter;
   1.150 +      public Int32 YPelsPerMeter;
   1.151 +      public Int32 ClrUsed;
   1.152 +      public Int32 ClrImportant;
   1.153 +      public Int32 Colors;
   1.154 +    }
   1.155 +
   1.156      public static readonly IntPtr HWND_BOTTOM = (IntPtr)1;
   1.157      public static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
   1.158  
   1.159 @@ -501,6 +555,11 @@
   1.160        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
   1.161  
   1.162        [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   1.163 +      public static extern IntPtr CreateDIBSection(IntPtr hdc, 
   1.164 +        [In] ref BitmapInfo pbmi, uint pila, out IntPtr ppvBits, 
   1.165 +        IntPtr hSection, uint dwOffset);
   1.166 +
   1.167 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   1.168        [return: MarshalAs(UnmanagedType.Bool)]
   1.169        public static extern bool DeleteDC(IntPtr hdc);
   1.170