C# Programming > Windows Forms

C# Capture Control Graphics

Control Graphics

To capture a .NET control's graphics into a Bitmap, programmers can use GDI to transfer what is rendered on the screen to a Bitmap.

Having an image representation is very useful. Developers can process the image in a number of ways. Another thing is the image can be drawn back to the screen, opening up a way to process a .NET control's graphics.

ControlPaint vs GDI

A fairly common way to "manually" draw .NET controls is to use the ControlPaint class. ControlPaint has static functions that can draw common .NET controls to a Graphic surface. For example, ControlPaint.DrawButton draws a button.

However this has two disadvantages. The first thing is that ControlPaint does not include support for every .NET control, not to mention user controls created by the developer. The second issue is ControlPaint does not take into account visual styles, thus the rendered control will not match the rest of the Form's controls.

A better way to capture a .NET control is to draw what is already drawn on the screen to a bitmap. GDI has the BitBlt function which allows C# developers to do that efficiently. The BitBlt function is located in the GDI32.dll:

[DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc,
int nXSrc,
int nYSrc,
int dwRop);

If you notice BitBlt is going to do most of the work for us. All we need to do is supply it the proper display device contexts (DC) values. One will be the control's DC and the other will be the destination bitmap's DC:

public Bitmap CaptureControl(Control control)
{
    Bitmap controlBmp;
    using (Graphics g1 = control.CreateGraphics())
    {
        controlBmp = new Bitmap(control.Width, control.Height, g1);
        using (Graphics g2 = Graphics.FromImage(controlBmp))
        {
            IntPtr dc1 = g1.GetHdc();
            IntPtr dc2 = g2.GetHdc();
            BitBlt(dc2, 0, 0, control.Width, control.Height, dc1, 0, 0, 13369376);
            g1.ReleaseHdc(dc1);
            g2.ReleaseHdc(dc2);
        }
    }

    return controlBmp;
}

Using the Code

Of course the source code has a few limitations. Since it is capturing the .NET control by copying what is rendered on the screen, if there is something on top of the captured control, then it will also be copied.

The advantage of course is that this function can capture any control, even user controls, in technically any state.

DrawToBitmap

It has been drawn to my attentinon that Control objects in the .NET Framework 2.0 and up have a function called DrawToBitmap which automatically handles the code described above for capturing a .NET control to a Bitmap. The code above is good for older .NET applications.

 

Back to C# Article List