ARTICLE
Screen capturing of a Form using GDI+
Tags: .NET, Bitmap, DllImportAttribute, Form Capturing in VB.NET., GDI+, GDI+ Graphics, MessageBox, Printing, Screen Capturing, System.Runtime.InteropServices, VB.NET, Windows Form
In most cases, GDI+ speeds up your programming of Graphics because (1) It is not a thin veneer over the Windows SDK (2) It makes sense. However, whenever you lose granularity to create a simpler to use architecture, you tend to lose some functionality. Form Capture is one of these cases. In the cases where you say to yourself: "Hey! I could do that in GDI, why can't I do that in GDI+??". The answer is you can.
Download
Files:

Figure 1 - Form captured into a jpeg file.
In most cases, GDI+ speeds up your programming of Graphics because (1) It is not a thin veneer over the Windows SDK (2) It makes sense. However, whenever you lose granularity to create a simpler to use architecture, you tend to lose some functionality. Form Capture is one of these cases. In the cases where you say to yourself: "Hey! I could do that in GDI, why can't I do that in GDI+??". The answer is you can.
VB.NET has an attribute that allows you to bring in virtually any pre-millennium Windows SDK dll. This, of course, includes the famed gdi.dll. The way to do this is shown below using the DllImportAttribute:
System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
The way to do form capture in GDI is to get the device context to the screen and bit blast it to a Bitmap in memory. The GDI external declaration for bit blasting is shown below (Note that this call has been converted to the equivalent call in C# so it can be used in our program):
Private Shared Function BitBlt(hdcDest As IntPtr, nXDest As Integer, nYDest As Integer, nWidth As Integer, nHeight As Integer, hdcSrc As IntPtr, nXSrc As Integer, nYSrc As Integer, dwRop As System.Int32) As Boolean
' handle to destination DC
' x-coord of destination upper-left corner
' y-coord of destination upper-left corner
' width of destination rectangle
' height of destination rectangle
' handle to source DC
' x-coordinate of source upper-left corner
' y-coordinate of source upper-left corner
' raster operation code
In order to use this GDI call in GDI+ you need to have hooks into the device contexts. Luckily GDI+ provides a method of getting the GDI device context through the GDI+ graphics object:
Dim dc1 As IntPtr = aGraphicsObject.GetHdc().
Now we'll put the whole thing together in our Form. Below is the series of calls needed to get the image from the form and stick it in a bitmap using the following steps:
- Get a graphics object to the Form on the screen.
- Create an empty bitmap the size of the Form's Client Area.
- Get the Device Context for the Form.
- Get the Device Context for the Bitmap.
- Bit Blast the Form on the screen into the Bitmap.
- Release the Device Context for the Form.
- Release the Device Context for the Bitmap.
- Save the Image into a jpeg File.
Remember, its important to release the GDI device context after your done using it to make the GDI call(s), otherwise GDI+ will have problems. Below is the full code for capturing the forms client area into a jpeg file:
Private Sub Capture_Click(sender As Object, e As System.EventArgs)
Dim g1 As Graphics = Me.CreateGraphics()
Dim MyImage = New Bitmap(Me.ClientRectangle.Width, Me.ClientRectangle.Height, g1)
Dim g2 As Graphics = Graphics.FromImage(MyImage)
Dim dc1 As IntPtr = g1.GetHdc()
Dim dc2 As IntPtr = g2.GetHdc()
BitBlt(dc2, 0, 0, Me.ClientRectangle.Width, Me.ClientRectangle.Height, dc1, 0, 0, 13369376)
g1.ReleaseHdc(dc1)
g2.ReleaseHdc(dc2)
MyImage.Save("")
MessageBox.Show("Finished Saving Image") '
End Sub 'Capture_Click