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