Removed the bitmap.GetHbitmap call for every redraw of the gadget. This should reduce dynamic memory allocation and freeing and removes some of the page faults increasing.
authormoel.mich
Wed, 22 Jun 2011 22:36:17 +0000
changeset 30244c0e7f76e9e
parent 301 d14ce71cef44
child 303 f6db7258890e
Removed the bitmap.GetHbitmap call for every redraw of the gadget. This should reduce dynamic memory allocation and freeing and removes some of the page faults increasing.
GUI/Gadget.cs
GUI/GadgetWindow.cs
     1.1 --- a/GUI/Gadget.cs	Sun Jun 19 14:14:00 2011 +0000
     1.2 +++ b/GUI/Gadget.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,25 +37,22 @@
    1.13  
    1.14  using System;
    1.15  using System.Drawing;
    1.16 -using System.Drawing.Drawing2D;
    1.17 -using System.Drawing.Imaging;
    1.18 -using System.Drawing.Text;
    1.19  using System.Windows.Forms;
    1.20  
    1.21  namespace OpenHardwareMonitor.GUI {
    1.22    public abstract class Gadget : IDisposable {
    1.23  
    1.24      private GadgetWindow window;
    1.25 -    private Bitmap buffer;
    1.26 -    private Graphics graphics;
    1.27  
    1.28      public Gadget() {
    1.29        this.window = new GadgetWindow();
    1.30 -      CreateBuffer();
    1.31 +      this.window.Paint += delegate(object sender, PaintEventArgs e) {
    1.32 +        OnPaint(e);
    1.33 +      };
    1.34      }
    1.35  
    1.36      public virtual void Dispose() {
    1.37 -      DisposeBuffer();
    1.38 +      window.Dispose();
    1.39      }
    1.40  
    1.41      public Point Location {
    1.42 @@ -148,27 +145,6 @@
    1.43        }
    1.44      }
    1.45  
    1.46 -    private void CreateBuffer() {
    1.47 -      this.buffer = new Bitmap(window.Size.Width, window.Size.Height, 
    1.48 -        PixelFormat.Format32bppArgb);
    1.49 -      this.graphics = Graphics.FromImage(this.buffer);
    1.50 -      if (Environment.OSVersion.Version.Major > 5) {
    1.51 -        this.graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
    1.52 -        this.graphics.SmoothingMode = SmoothingMode.HighQuality;
    1.53 -      }
    1.54 -    }
    1.55 -
    1.56 -    private void DisposeBuffer() {
    1.57 -      if (buffer != null) {
    1.58 -        this.buffer.Dispose();
    1.59 -        this.buffer = null;
    1.60 -      }
    1.61 -      if (graphics != null) {
    1.62 -        this.graphics.Dispose();
    1.63 -        this.graphics = null;
    1.64 -      }
    1.65 -    }
    1.66 -
    1.67      public bool Visible {
    1.68        get {
    1.69          return window.Visible;
    1.70 @@ -187,17 +163,7 @@
    1.71      public event EventHandler VisibleChanged;
    1.72  
    1.73      public void Redraw() {
    1.74 -      if (!window.Visible)
    1.75 -        return;
    1.76 -      
    1.77 -      if (window.Size != buffer.Size) {
    1.78 -        DisposeBuffer();
    1.79 -        CreateBuffer();
    1.80 -      }
    1.81 -
    1.82 -      OnPaint(new PaintEventArgs(graphics, 
    1.83 -        new Rectangle(Point.Empty, window.Size)));
    1.84 -      window.Update(buffer);
    1.85 +      window.Redraw();
    1.86      }
    1.87  
    1.88      protected abstract void OnPaint(PaintEventArgs e);
     2.1 --- a/GUI/GadgetWindow.cs	Sun Jun 19 14:14:00 2011 +0000
     2.2 +++ b/GUI/GadgetWindow.cs	Wed Jun 22 22:36:17 2011 +0000
     2.3 @@ -16,7 +16,7 @@
     2.4  
     2.5    The Initial Developer of the Original Code is 
     2.6    Michael Möller <m.moeller@gmx.ch>.
     2.7 -  Portions created by the Initial Developer are Copyright (C) 2010
     2.8 +  Portions created by the Initial Developer are Copyright (C) 2010-2011
     2.9    the Initial Developer. All Rights Reserved.
    2.10  
    2.11    Contributor(s):
    2.12 @@ -37,13 +37,15 @@
    2.13  
    2.14  using System;
    2.15  using System.Drawing;
    2.16 +using System.Drawing.Drawing2D;
    2.17 +using System.Drawing.Text;
    2.18  using System.Reflection;
    2.19  using System.Runtime.InteropServices;
    2.20  using System.Windows.Forms;
    2.21  
    2.22  namespace OpenHardwareMonitor.GUI {
    2.23  
    2.24 -  public class GadgetWindow : NativeWindow {
    2.25 +  public class GadgetWindow : NativeWindow, IDisposable {
    2.26  
    2.27      private bool visible = false;
    2.28      private bool lockPositionAndSize = false;
    2.29 @@ -53,6 +55,9 @@
    2.30      private Size size = new Size(130, 84);
    2.31      private ContextMenu contextMenu = null;
    2.32      private MethodInfo commandDispatch;
    2.33 +    private IntPtr handleBitmapDC;
    2.34 +    private Size bufferSize;
    2.35 +    private Graphics graphics;
    2.36  
    2.37      public GadgetWindow() {
    2.38        Type commandType = 
    2.39 @@ -73,6 +78,8 @@
    2.40            WindowAttribute.DWMWA_EXCLUDED_FROM_PEEK, ref value,
    2.41            Marshal.SizeOf(value));
    2.42        } catch (DllNotFoundException) { } catch (EntryPointNotFoundException) { }
    2.43 +
    2.44 +      CreateBuffer();
    2.45      }
    2.46  
    2.47      private void ShowDesktopChanged(bool showDesktop) {
    2.48 @@ -223,35 +230,66 @@
    2.49        return blend;
    2.50      }
    2.51  
    2.52 -    public void Update(Bitmap bitmap) {
    2.53 -      IntPtr screen = NativeMethods.GetDC(IntPtr.Zero);
    2.54 -      IntPtr memory = NativeMethods.CreateCompatibleDC(screen);
    2.55 -      IntPtr newHBitmap = IntPtr.Zero;
    2.56 -      IntPtr oldHBitmap = IntPtr.Zero;
    2.57 +    private void CreateBuffer() {      
    2.58 +      IntPtr handleScreenDC = NativeMethods.GetDC(IntPtr.Zero);
    2.59 +      handleBitmapDC = NativeMethods.CreateCompatibleDC(handleScreenDC);
    2.60 +      NativeMethods.ReleaseDC(IntPtr.Zero, handleScreenDC);
    2.61 +      bufferSize = size;
    2.62  
    2.63 -      try {
    2.64 -        newHBitmap = bitmap.GetHbitmap(Color.Black);
    2.65 -        oldHBitmap = NativeMethods.SelectObject(memory, newHBitmap);
    2.66 +      BitmapInfo info = new BitmapInfo();
    2.67 +      info.Size = Marshal.SizeOf(info);
    2.68 +      info.Width = size.Width;
    2.69 +      info.Height = -size.Height;
    2.70 +      info.BitCount = 32;
    2.71 +      info.Planes = 1;
    2.72 +
    2.73 +      IntPtr ptr;
    2.74 +      IntPtr hBmp = NativeMethods.CreateDIBSection(handleBitmapDC, ref info, 0, 
    2.75 +        out ptr, IntPtr.Zero, 0);
    2.76 +      IntPtr hBmpOld = NativeMethods.SelectObject(handleBitmapDC, hBmp);
    2.77 +      NativeMethods.DeleteObject(hBmpOld);
    2.78 +      
    2.79 +      graphics = Graphics.FromHdc(handleBitmapDC);
    2.80 +
    2.81 +      if (Environment.OSVersion.Version.Major > 5) {
    2.82 +        this.graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
    2.83 +        this.graphics.SmoothingMode = SmoothingMode.HighQuality;
    2.84 +      } 
    2.85 +    }
    2.86 +
    2.87 +    private void DisposeBuffer() {
    2.88 +      graphics.Dispose();
    2.89 +      NativeMethods.DeleteDC(handleBitmapDC);
    2.90 +    }
    2.91 +
    2.92 +    public virtual void Dispose() {
    2.93 +      DisposeBuffer();
    2.94 +    } 
    2.95 +
    2.96 +    public PaintEventHandler Paint; 
    2.97 +
    2.98 +    public void Redraw() {
    2.99 +      if (!visible || Paint == null)
   2.100 +        return;
   2.101 +
   2.102 +      if (size != bufferSize) {
   2.103 +        DisposeBuffer();
   2.104 +        CreateBuffer();
   2.105 +      }
   2.106 +
   2.107 +      Paint(this, 
   2.108 +        new PaintEventArgs(graphics, new Rectangle(Point.Empty, size))); 
   2.109  
   2.110          Point pointSource = Point.Empty;
   2.111          BlendFunction blend = CreateBlendFunction();
   2.112  
   2.113 -        NativeMethods.UpdateLayeredWindow(Handle, screen, IntPtr.Zero,
   2.114 -          ref size, memory, ref pointSource, 0, ref blend, ULW_ALPHA);
   2.115 +        NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero, IntPtr.Zero,
   2.116 +          ref size, handleBitmapDC, ref pointSource, 0, ref blend, ULW_ALPHA);
   2.117  
   2.118          // make sure the window is at the right location
   2.119 -        NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 
   2.120 -          location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | 
   2.121 +        NativeMethods.SetWindowPos(Handle, IntPtr.Zero,
   2.122 +          location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE |
   2.123            SWP_NOZORDER | SWP_NOSENDCHANGING);
   2.124 -
   2.125 -      } finally {        
   2.126 -        if (newHBitmap != IntPtr.Zero) {
   2.127 -          NativeMethods.SelectObject(memory, oldHBitmap);
   2.128 -          NativeMethods.DeleteObject(newHBitmap);
   2.129 -        }
   2.130 -        NativeMethods.DeleteDC(memory);
   2.131 -        NativeMethods.ReleaseDC(IntPtr.Zero, screen);
   2.132 -      }
   2.133      }
   2.134  
   2.135      public byte Opacity {
   2.136 @@ -386,6 +424,22 @@
   2.137        public uint flags;
   2.138      }
   2.139  
   2.140 +    [StructLayout(LayoutKind.Sequential)]
   2.141 +    public struct BitmapInfo {
   2.142 +      public Int32 Size;
   2.143 +      public Int32 Width;
   2.144 +      public Int32 Height;
   2.145 +      public Int16 Planes;
   2.146 +      public Int16 BitCount;
   2.147 +      public Int32 Compression;
   2.148 +      public Int32 SizeImage;
   2.149 +      public Int32 XPelsPerMeter;
   2.150 +      public Int32 YPelsPerMeter;
   2.151 +      public Int32 ClrUsed;
   2.152 +      public Int32 ClrImportant;
   2.153 +      public Int32 Colors;
   2.154 +    }
   2.155 +
   2.156      public static readonly IntPtr HWND_BOTTOM = (IntPtr)1;
   2.157      public static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
   2.158  
   2.159 @@ -501,6 +555,11 @@
   2.160        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
   2.161  
   2.162        [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.163 +      public static extern IntPtr CreateDIBSection(IntPtr hdc, 
   2.164 +        [In] ref BitmapInfo pbmi, uint pila, out IntPtr ppvBits, 
   2.165 +        IntPtr hSection, uint dwOffset);
   2.166 +
   2.167 +      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
   2.168        [return: MarshalAs(UnmanagedType.Bool)]
   2.169        public static extern bool DeleteDC(IntPtr hdc);
   2.170