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.
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