Esempio n. 1
0
        protected override void OnPaint(PaintEventArgs e)
        {
            var outerBounds = new Rectangle(0, 0, Width, Height);

            using (var target = new Bitmap(outerBounds.Width, outerBounds.Height, PixelFormat.Format32bppArgb))
            {
                using (var targetGraphics = Graphics.FromImage(target))
                {
                    // The top and bottom borders extend over the sides of the window.
                    // The left and right borders do no. This means that we need to
                    // update the bounds to make it seem like the left and right
                    // borders do extend outside of the window.

                    if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Right)
                    {
                        outerBounds = new Rectangle(
                            outerBounds.Left,
                            outerBounds.Top - _borderWidth,
                            outerBounds.Width,
                            outerBounds.Height + _borderWidth * 2
                            );
                    }

                    if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Top)
                    {
                        DrawImage(targetGraphics, _imageCache.CornerNW,
                                  new Point(outerBounds.Left, outerBounds.Top)
                                  );
                    }

                    if (Border == DropShadowBorder.Right || Border == DropShadowBorder.Top)
                    {
                        DrawImage(targetGraphics, _imageCache.CornerNE,
                                  new Point(outerBounds.Right - _cornerSize, outerBounds.Top)
                                  );
                    }

                    if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Left)
                    {
                        DrawImage(targetGraphics, _imageCache.CornerSW,
                                  new Point(outerBounds.Left, outerBounds.Bottom - _cornerSize)
                                  );
                    }

                    if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Right)
                    {
                        DrawImage(targetGraphics, _imageCache.CornerSE,
                                  new Point(outerBounds.Right - _cornerSize, outerBounds.Bottom - _cornerSize)
                                  );
                    }

                    if (Border == DropShadowBorder.Top)
                    {
                        DrawBorder(targetGraphics, _imageCache.BorderN,
                                   new Rectangle(
                                       outerBounds.Left + _cornerSize,
                                       outerBounds.Top,
                                       outerBounds.Width - _cornerSize * 2,
                                       _borderWidth
                                       )
                                   );
                    }

                    if (Border == DropShadowBorder.Bottom)
                    {
                        DrawBorder(targetGraphics, _imageCache.BorderS,
                                   new Rectangle(
                                       outerBounds.Left + _cornerSize,
                                       outerBounds.Bottom - _borderWidth,
                                       outerBounds.Width - _cornerSize * 2,
                                       _borderWidth
                                       )
                                   );
                    }

                    if (Border == DropShadowBorder.Left)
                    {
                        DrawBorder(targetGraphics, _imageCache.BorderW,
                                   new Rectangle(
                                       outerBounds.Left,
                                       outerBounds.Top + _cornerSize,
                                       _borderWidth,
                                       outerBounds.Height - _cornerSize * 2
                                       )
                                   );
                    }

                    if (Border == DropShadowBorder.Right)
                    {
                        DrawBorder(targetGraphics, _imageCache.BorderE,
                                   new Rectangle(
                                       outerBounds.Right - _borderWidth,
                                       outerBounds.Top + _cornerSize,
                                       _borderWidth,
                                       outerBounds.Height - _cornerSize * 2
                                       )
                                   );
                    }
                }

                // Get device contexts
                var screenDc   = PI.GetDC(IntPtr.Zero);
                var memDc      = PI.CreateCompatibleDC(screenDc);
                var hBitmap    = IntPtr.Zero;
                var hOldBitmap = IntPtr.Zero;

                try
                {
                    // Get handle to the new bitmap and select it into the current device context
                    hBitmap    = target.GetHbitmap(Color.FromArgb(0));
                    hOldBitmap = PI.SelectObject(memDc, hBitmap);  // Set parameters for layered window update

                    var newSize        = new PI.SIZE(target.Size); // Size window to match bitmap
                    var sourceLocation = new PI.POINT(Point.Empty);
                    var newLocation    = new PI.POINT(Location);   // Same as this window

                    var blend = new PI.BLENDFUNCTION
                    {
                        BlendOp             = PI.AC_SRC_OVER, // Only works with a 32bpp bitmap
                        BlendFlags          = 0,              // Always 0
                        SourceConstantAlpha = 255,            // Set to 255 for per-pixel alpha values
                        AlphaFormat         = PI.AC_SRC_ALPHA // Only works when the bitmap contains an alpha channel
                    };

                    // Update the window
                    PI.UpdateLayeredWindow(
                        Handle, screenDc, ref newLocation, ref newSize,
                        memDc, ref sourceLocation, 0, ref blend,
                        PI.ULW_ALPHA
                        );
                }
                finally
                {
                    // Release device context
                    PI.ReleaseDC(IntPtr.Zero, screenDc);

                    if (hBitmap != IntPtr.Zero)
                    {
                        PI.SelectObject(memDc, hOldBitmap);
                        PI.DeleteObject(hBitmap); // Remove bitmap resources
                    }

                    PI.DeleteDC(memDc);
                }
            }
        }