/*public static void DrawGlowingText(this VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, string text, Font font, Color color, System.Windows.Forms.TextFormatFlags flags)
         * {
         *      using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
         *      {
         *              // Create a memory DC so we can work offscreen
         *              using (SafeCompatibleDCHandle memoryHdc = new SafeCompatibleDCHandle(primaryHdc))
         *              {
         *                      // Create a device-independent bitmap and select it into our DC
         *                      BITMAPINFO info = new BITMAPINFO(bounds.Width, -bounds.Height);
         *                      using (SafeDCObjectHandle dib = new SafeDCObjectHandle(memoryHdc, GDI.CreateDIBSection(primaryHdc, ref info, 0, 0, IntPtr.Zero, 0)))
         *                      {
         *                              // Create and select font
         *                              using (SafeDCObjectHandle fontHandle = new SafeDCObjectHandle(memoryHdc, font.ToHfont()))
         *                              {
         *                                      // Draw glowing text
         *                                      DrawThemeTextOptions dttOpts = new DrawThemeTextOptions(true);
         *                                      dttOpts.TextColor = color;
         *                                      dttOpts.GlowSize = 10;
         *                                      dttOpts.AntiAliasedAlpha = true;
         *                                      NativeMethods.RECT textBounds = new NativeMethods.RECT(4, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
         *                                      DrawThemeTextEx(rnd.Handle, memoryHdc, rnd.Part, rnd.State, text, text.Length, (int)flags, ref textBounds, ref dttOpts);
         *
         *                                      // Copy to foreground
         *                                      const int SRCCOPY = 0x00CC0020;
         *                                      GDI.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
         *                              }
         *                      }
         *              }
         *      }
         * }*/

        private static void DrawWrapper(VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, DrawWrapperMethod func)
        {
            using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
            {
                // Create a memory DC so we can work offscreen
                using (NativeMethods.SafeCompatibleDCHandle memoryHdc = new NativeMethods.SafeCompatibleDCHandle(primaryHdc))
                {
                    // Create a device-independent bitmap and select it into our DC
                    NativeMethods.BITMAPINFO info = new NativeMethods.BITMAPINFO(bounds.Width, -bounds.Height);
                    using (NativeMethods.SafeDCObjectHandle dib = new NativeMethods.SafeDCObjectHandle(memoryHdc, NativeMethods.CreateDIBSection(primaryHdc, ref info, 0, IntPtr.Zero, IntPtr.Zero, 0)))
                    {
                        // Call method
                        func(memoryHdc);

                        // Copy to foreground
                        const int SRCCOPY = 0x00CC0020;
                        NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
                    }
                }
            }
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            if (BufferedPaintSupported)
            {
                bool stateChanged = !Object.Equals(currentState, newState);

                using (var hdc = new SafeGDIHandle(e.Graphics))
                {
                    if (!hdc.IsInvalid)
                    {
                        // see if this paint was generated by a soft-fade animation
                        if (!NativeMethods.BufferedPaintRenderAnimation(this.Handle, hdc))
                        {
                            NativeMethods.BufferedPaintAnimationParams animParams = new NativeMethods.BufferedPaintAnimationParams(NativeMethods.BufferedPaintAnimationStyle.Linear);

                            // get appropriate animation time depending on state transition (or 0 if unchanged)
                            if (stateChanged)
                            {
                                foreach (var item in transitions)
                                {
                                    if (item.currentState == currentState && item.newState == newState)
                                    {
                                        animParams.Duration = item.duration;
                                        break;
                                    }
                                }
                            }

                            Rectangle rc = this.ClientRectangle;
                            IntPtr    hdcFrom, hdcTo;
                            IntPtr    hbpAnimation = NativeMethods.BeginBufferedAnimation(this.Handle, hdc, ref rc, NativeMethods.BufferedPaintBufferFormat.CompatibleBitmap, IntPtr.Zero, ref animParams, out hdcFrom, out hdcTo);
                            if (hbpAnimation != IntPtr.Zero)
                            {
                                if (hdcFrom != IntPtr.Zero)
                                {
                                    using (Graphics gfxFrom = Graphics.FromHdc(hdcFrom))
                                        PaintControl(new PaintEventArgs(gfxFrom, e.ClipRectangle));
                                }
                                currentState = newState;
                                if (hdcTo != IntPtr.Zero)
                                {
                                    using (Graphics gfxTo = Graphics.FromHdc(hdcTo))
                                        PaintControl(new PaintEventArgs(gfxTo, e.ClipRectangle));
                                }
                                NativeMethods.EndBufferedAnimation(hbpAnimation, true);
                            }
                            else
                            {
                                hdc.Dispose();
                                currentState = newState;
                                PaintControl(e);
                            }
                        }
                    }
                }
            }
            else
            {
                // buffered painting not supported, just paint using the current state
                currentState = newState;
                PaintControl(e);
            }
        }