PageRenderTime 56ms CodeModel.GetById 18ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/Skimpt3/Skimpt3/classes/skCustomForm.cs

http://skimpt.googlecode.com/
C# | 360 lines | 263 code | 60 blank | 37 comment | 23 complexity | fe4e3196e2881e0bc615cc70284dff03 MD5 | raw file
  1using System;
  2using System.Windows.Forms;
  3using System.Drawing;
  4using System.Drawing.Imaging;
  5using System.Runtime.InteropServices;
  6using System.ComponentModel;
  7using System.Diagnostics;
  8
  9namespace Skimpt3.classes {
 10    public  class skCustomForm : Form {
 11
 12        [Category("Appearance"),
 13            Description("Occurs when the layered form needs repainting.")]
 14        protected event EventHandler<PaintLayerEventArgs> PaintLayer;
 15        private bool freezePainting;
 16        private double layerOpacity = 1.0;
 17
 18        public double LayerOpacity {
 19            get { return layerOpacity; }
 20            set {
 21                if (value > 1)
 22                    layerOpacity = 1.0;
 23                else if (value < 0)
 24                    layerOpacity = 0.0;
 25                else
 26                    layerOpacity = value;
 27
 28                PaintLayeredWindow();
 29            }
 30        }
 31
 32        private byte LayerOpacityAsByte {
 33            get { return ((byte)(layerOpacity * 255)); }
 34        }
 35
 36        public bool FreezePainting {
 37            get { return freezePainting; }
 38            set {
 39                if (value == false)
 40                    PaintLayeredWindow();             
 41                freezePainting = value;
 42            }
 43        }
 44
 45        protected skCustomForm() {
 46            FormBorderStyle = FormBorderStyle.None;
 47            ShowInTaskbar = false;
 48            StartPosition = FormStartPosition.Manual;
 49            InitializeComponent();
 50            Debug.WriteLine("Base - constructor");
 51        }
 52
 53        private void InitializeComponent()
 54        {
 55            //this.clientSize calls the onPaintLayer internally. Which means it 
 56            //calls the OnPaintLayer method in the derived class. Which in turn 
 57            //calls the base OnPaintLayer which invokes the event.
 58
 59            Debug.WriteLine("Initilizing base");
 60            this.SuspendLayout();
 61            this.ClientSize = new System.Drawing.Size(280, 260);
 62            this.Name = "skCustomForm";          
 63            this.ResumeLayout(false);
 64
 65        }
 66        /// <summary>
 67        /// Raises the <see cref="PaintLayer"/> event.
 68        /// </summary>
 69        /// <param name="e">A <see cref="PaintLayerEventArgs"/> object containing the 
 70        /// event data.</param>
 71        protected virtual void OnPaintLayer(PaintLayerEventArgs e) {       
 72            EventHandler<PaintLayerEventArgs> handler = PaintLayer;
 73            if (!DesignMode && (handler != null))
 74                PaintLayer(this, e);
 75        }
 76
 77        protected void PaintLayeredWindow() {
 78            if (Bounds.Size != Size.Empty) {
 79                using (Bitmap surface = new Bitmap(ClientRectangle.Width, ClientRectangle.Height, PixelFormat.Format32bppArgb))
 80                    PaintLayeredWindow(surface);
 81            }
 82          
 83        }
 84
 85        protected void PaintLayeredWindow(Bitmap bitmap) {
 86            if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
 87                throw new ArgumentException("The bitmap must be 32bpp with an alpha-channel.", "bitmap");          
 88
 89            using (PaintLayerEventArgs args = new PaintLayerEventArgs(bitmap)) {
 90                OnPaintLayer(args);
 91                PaintNative(bitmap, LayerOpacityAsByte);
 92            }
 93            Console.WriteLine("PaintLayerdWindow base");
 94        }
 95
 96        private void PaintNative(Bitmap bitmap, byte opacity) {
 97            Debug.WriteLine("PaintNative");
 98            IntPtr hdcDestination = NativeMethods.GetDC(IntPtr.Zero);
 99            IntPtr hdcSource = NativeMethods.CreateCompatibleDC(hdcDestination);
100            IntPtr hdcBitmap = IntPtr.Zero;
101            IntPtr previousBitmap = IntPtr.Zero;
102            try {
103                hdcBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
104                previousBitmap = NativeMethods.SelectObject(hdcSource, hdcBitmap);
105
106                NativeMethods.SIZE size = new NativeMethods.SIZE(bitmap.Width, bitmap.Height);
107                NativeMethods.POINT source = new NativeMethods.POINT(0, 0);
108                NativeMethods.POINT destination = new NativeMethods.POINT(Left, Top);
109                NativeMethods.BLENDFUNCTION blend = new NativeMethods.BLENDFUNCTION();
110
111                blend.BlendOp = NativeMethods.AC_SRC_OVER;
112                blend.BlendFlags = 0;
113                blend.SourceConstantAlpha = opacity;
114                blend.AlphaFormat = NativeMethods.AC_SRC_ALPHA;
115
116                NativeMethods.UpdateLayeredWindow(
117                    Handle,
118                    hdcDestination,
119                    ref destination,
120                    ref size,
121                    hdcSource,
122                    ref source,
123                    0,
124                    ref blend,
125                    2);
126            } catch (Exception) {
127                return;
128            } finally {
129                NativeMethods.ReleaseDC(IntPtr.Zero, hdcDestination);
130                if (hdcBitmap != IntPtr.Zero) {
131                    NativeMethods.SelectObject(hdcSource, previousBitmap);
132                    NativeMethods.DeleteObject(hdcBitmap);
133                }
134                NativeMethods.DeleteDC(hdcSource);
135            }
136        }
137
138        protected override void OnResize(EventArgs e) {
139            if (!freezePainting) {
140                PaintLayeredWindow();
141                base.OnResize(e);
142            }          
143        }
144
145        protected override CreateParams CreateParams {
146            get {
147                CreateParams cParams = base.CreateParams;
148                cParams.ExStyle |= NativeMethods.WS_EX_LAYERED;
149                return cParams;
150            }
151        }       
152    }
153
154    public class PaintLayerEventArgs : EventArgs, IDisposable {
155        #region Member Fields
156
157        private readonly Graphics graphics;
158        private readonly Bitmap surface;
159        private readonly Size size;
160
161        #endregion
162
163        #region Property Accessors
164
165        /// <summary>
166        /// Gets the bounds.
167        /// </summary>
168        /// <value>The bounds.</value>
169        public Rectangle Bounds {
170            get { return new Rectangle(Point.Empty, Size); }
171        }
172
173        /// <summary>
174        /// Gets the size.
175        /// </summary>
176        /// <value>The size.</value>
177        public Size Size {
178            get { return size; }
179        }
180
181        /// <summary>
182        /// Gets the graphics.
183        /// </summary>
184        /// <value>The graphics.</value>
185        public Graphics Graphics {
186            get { return graphics; }
187        }
188
189        /// <summary>
190        /// Gets the image.
191        /// </summary>
192        /// <value>The image.</value>
193        internal Bitmap Image {
194            get { return surface; }
195        }
196
197        #endregion
198
199        /// <summary>
200        /// Initializes a new instance of the <see cref="PaintLayerEventArgs"/> class.
201        /// </summary>
202        public PaintLayerEventArgs() { }
203
204        /// <summary>
205        /// Initializes a new instance of the <see cref="PaintLayerEventArgs"/> class.
206        /// </summary>
207        /// <param name="bitmap">The bitmap.</param>
208        internal PaintLayerEventArgs(Bitmap bitmap) {
209            surface = bitmap;
210            graphics = Graphics.FromImage(surface);
211            //graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
212            size = new Size(bitmap.Width, bitmap.Height);
213        }
214
215        /// <summary>
216        /// Disposes this instance.
217        /// </summary>
218        public void Dispose() {
219            if (graphics != null)
220                graphics.Dispose();
221            if (surface != null)
222                surface.Dispose();
223        }
224    }
225
226    internal sealed class NativeMethods {
227        //============== GDI32 CONSTANTS =============== 
228        public const Int32 CAPTUREBLT = 0x40000000;
229        public const Int32 BLACKNESS = 0x42;
230        public const Int32 DSTINVERT = 0x550009;
231        public const Int32 MERGECOPY = 0xc000ca;
232        public const Int32 MERGEPAINT = 0xbb0226;
233        public const Int32 NOTSRCCOPY = 0x330008;
234        public const Int32 NOTSRCERASE = 0x1100a6;
235        public const Int32 PATCOPY = 0xf00021;
236        public const Int32 PATINVERT = 0x5a0049;
237        public const Int32 PATPAINT = 0xfb0a09;
238        public const Int32 SRCAND = 0x8800c6;
239        public const Int32 SRCCOPY = 0xcc0020;
240        public const Int32 SRCERASE = 0x440328;
241        public const Int32 SRCINVERT = 0x660046;
242        public const Int32 SRCPAINT = 0xee0086;
243        public const Int32 WHITENESS = 0xff0062;
244
245        public const Int32 HORZRES = 8;
246        public const Int32 VERTRES = 10;
247        //=========================================== 
248
249        private NativeMethods() { }
250
251        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
252        [return: MarshalAs(UnmanagedType.Bool)]
253        internal static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vic);
254
255        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
256        [return: MarshalAs(UnmanagedType.Bool)]
257        internal static extern bool UnregisterHotKey(IntPtr hWnd, int id);
258
259        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
260        internal static extern ushort GlobalAddAtom(string lpString);
261
262        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
263        internal static extern ushort GlobalDeleteAtom(ushort nAtom);
264
265        [DllImport("gdi32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
266        internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
267
268        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
269        internal static extern IntPtr GetDC(IntPtr hWnd);
270
271        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
272        internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
273
274        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
275        [return: MarshalAs(UnmanagedType.Bool)]
276        internal static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref POINT pptDst, ref SIZE psize, IntPtr hdcSrc, ref POINT pprSrc, int crKey, ref BLENDFUNCTION pblend, int dwFlags);
277
278        [DllImport("gdi32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
279        internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
280
281        [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = false)]
282        internal static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
283
284        [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = false)]
285        internal static extern int SendMessage(IntPtr hWnd, int msg, int wParam, string lParam);
286
287        [DllImport("user32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
288        internal static extern IntPtr GetWindow(IntPtr hwnd, int cmd);
289
290        [DllImport("gdi32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
291        [return: MarshalAs(UnmanagedType.Bool)]
292        internal static extern bool DeleteDC(IntPtr hdc);
293
294        [DllImport("gdi32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
295        [return: MarshalAs(UnmanagedType.Bool)]
296        internal static extern bool DeleteObject(IntPtr hObject);
297
298        [DllImport("gdi32", SetLastError = true)]
299        [return: MarshalAs(UnmanagedType.Bool)]
300        public static extern bool BitBlt(IntPtr hdcDest, Int32 nXDest, Int32 nYDest, Int32 nWidth, Int32 nHeight, IntPtr hdcSrc, Int32 nXSrc, Int32 nYSrc, Int32 dwRop);
301
302
303        internal const Int32 WM_SETICON = 0x80;
304        internal const Int32 WM_SETTEXT = 0x000c;
305        internal const Int32 GW_OWNER = 4;
306        internal const Int32 ICON_SMALL = 0;
307        internal const Int32 ICON_BIG = 1;
308        internal const Int32 WS_EX_LAYERED = 0x80000;
309        internal const Int32 WM_HOTKEY = 0x0312;
310
311        internal const Byte AC_SRC_OVER = 0x00;
312        internal const Byte AC_SRC_ALPHA = 0x01;
313
314        [StructLayout(LayoutKind.Sequential, Pack = 1)]
315        internal struct BLENDFUNCTION {
316            public byte BlendOp;
317            public byte BlendFlags;
318            public byte SourceConstantAlpha;
319            public byte AlphaFormat;
320        }
321
322        [StructLayout(LayoutKind.Sequential)]
323        internal struct POINT {
324            public int X;
325            public int Y;
326
327            public POINT(int x, int y) {
328                X = x;
329                Y = y;
330            }
331
332            public static explicit operator POINT(Point pt) {
333                return new POINT(pt.X, pt.Y);
334            }
335        }
336
337        [StructLayout(LayoutKind.Sequential)]
338        internal struct SIZE {
339            public int Width;
340            public int Height;
341
342            public SIZE(int w, int h) {
343                Width = w;
344                Height = h;
345            }
346        }
347
348        internal static IntPtr GetTopLevelOwner(IntPtr hWnd) {
349            IntPtr hwndOwner = hWnd;
350            IntPtr hwndCurrent = hWnd;
351            while (hwndCurrent != (IntPtr)0) {
352                hwndCurrent = GetWindow(hwndCurrent, GW_OWNER);
353                if (hwndCurrent != (IntPtr)0) {
354                    hwndOwner = hwndCurrent;
355                }
356            }
357            return hwndOwner;
358        }
359    }
360}