public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
		{
			if (!RenderClientAreas ||
				!VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Bar.Normal) ||
				!VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Chunk.Normal)) {
				base.DrawProgressBar (dc, clip_rect, ctrl);
				return;
			}
			VisualStyleRenderer renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Bar.Normal);
			renderer.DrawBackground (dc, ctrl.ClientRectangle, clip_rect);
			Rectangle client_area = renderer.GetBackgroundContentRectangle (dc, new Rectangle (Point.Empty, ctrl.Size));
			renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Chunk.Normal);
			/* Draw Blocks */
			int draw_mode = 0;
			int max_blocks = int.MaxValue;
			int start_pixel = client_area.X;
#if NET_2_0
			draw_mode = (int)ctrl.Style;
#endif
			switch (draw_mode) {
#if NET_2_0
			case 1: // Continuous
				client_area.Width = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max (ctrl.Maximum - ctrl.Minimum, 1))));
				renderer.DrawBackground (dc, client_area, clip_rect);
				break;
			case 2: // Marquee
				int ms_diff = (int)(DateTime.Now - ctrl.start).TotalMilliseconds;
				double percent_done = (double)ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
				max_blocks = 5;
				start_pixel = client_area.X + (int)(client_area.Width * percent_done);
				goto default;
#endif
			default: // Blocks
				int block_width = renderer.GetInteger (IntegerProperty.ProgressChunkSize);
				block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0!
				int first_pixel_outside_filled_area = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1))) + client_area.X;
				int block_count = 0;
				int increment = block_width + renderer.GetInteger (IntegerProperty.ProgressSpaceSize);
				Rectangle block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
				while (true) {
					if (max_blocks != int.MaxValue) {
						if (block_count == max_blocks)
							break;
						if (block_rect.Right >= client_area.Width)
							block_rect.X -= client_area.Width;
					} else {
						if (block_rect.X >= first_pixel_outside_filled_area)
							break;
						if (block_rect.Right >= first_pixel_outside_filled_area)
							if (first_pixel_outside_filled_area == client_area.Right)
								block_rect.Width = first_pixel_outside_filled_area - block_rect.X;
							else
								break;
					}
					if (clip_rect.IntersectsWith (block_rect))
						renderer.DrawBackground (dc, block_rect, clip_rect);
					block_rect.X += increment;
					block_count++;
				}
				break;
			}
		}
        /// <summary>
        /// Gets the background image of the current visual style element within the specified background color. If <paramref name="states"/> is set, the resulting image will contain each of the state images side by side.
        /// </summary>
        /// <param name="rnd">The <see cref="VisualStyleRenderer"/> instance.</param>
        /// <param name="clr">The background color. This color cannot have an alpha channel.</param>
        /// <param name="states">The optional list of states to render side by side.</param>
        /// <returns>The background image.</returns>
        public static Bitmap GetBackgroundBitmap(this VisualStyleRenderer rnd, Color clr, int[] states = null)
        {
            const int wh = 200;

            if (rnd == null)
            {
                throw new ArgumentNullException(nameof(rnd));
            }
            rnd.SetParameters(rnd.Class, rnd.Part, 0);
            if (states == null)
            {
                states = new[] { rnd.State }
            }
            ;
            var i = states.Length;

            // Get image size
            Size imgSz;

            using (var sg = Graphics.FromHwnd(IntPtr.Zero))
                imgSz = rnd.GetPartSize(sg, new Rectangle(0, 0, wh, wh), ThemeSizeType.Draw);
            if (imgSz.Width == 0 || imgSz.Height == 0)
            {
                imgSz = new Size(rnd.GetInteger(IntegerProperty.Width), rnd.GetInteger(IntegerProperty.Height));
            }

            var bounds = new Rectangle(0, 0, imgSz.Width * i, imgSz.Height);

            // Draw each background linearly down the bitmap
            using (var memoryHdc = SafeDCHandle.ScreenCompatibleDCHandle)
            {
                // Create a device-independent bitmap and select it into our DC
                var    info = new BITMAPINFO(bounds.Width, -bounds.Height);
                IntPtr ppv;
                using (new SafeDCObjectHandle(memoryHdc, CreateDIBSection(SafeDCHandle.Null, ref info, DIBColorMode.DIB_RGB_COLORS, out ppv, IntPtr.Zero, 0)))
                {
                    using (var memoryGraphics = Graphics.FromHdc(memoryHdc.DangerousGetHandle()))
                    {
                        // Setup graphics
                        memoryGraphics.CompositingMode    = CompositingMode.SourceOver;
                        memoryGraphics.CompositingQuality = CompositingQuality.HighQuality;
                        memoryGraphics.SmoothingMode      = SmoothingMode.HighQuality;
                        memoryGraphics.Clear(clr);

                        // Draw each background linearly down the bitmap
                        var rect = new Rectangle(0, 0, imgSz.Width, imgSz.Height);
                        foreach (var state in states)
                        {
                            rnd.SetParameters(rnd.Class, rnd.Part, state);
                            rnd.DrawBackground(memoryGraphics, rect);
                            rect.X += imgSz.Width;
                        }
                    }

                    // Copy DIB to Bitmap
                    var bmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
                    using (var primaryHdc = new SafeDCHandle(Graphics.FromImage(bmp)))
                        BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, RasterOperationMode.SRCCOPY);
                    return(bmp);
                }
            }
        }