Create Screen Dump of a Windows Form

Recently, friend Paul Sheriff sent this email:

Remember in VB6 we had the Me.Print and it would print the bitmap of the form? Is there anyway to do that in VB.NET?

I sat on it for a while, knowing that it would be fun to work out, once I got to it. Turns out, in VS 2005, it's really easy. The Control class adds a DrawToBitmap method, so you can create a method like this to do the work:

Public Function GetFormImage(ByVal frm As Form) As Bitmap
  Dim bmp As Bitmap
  Using g As Graphics = Me.CreateGraphics()
    Dim sz As Size = frm.Size
    bmp = New Bitmap(sz.Width, sz.Height, g)
    frm.DrawToBitmap(bmp, New Rectangle(0, 0, sz.Width, sz.Height))
  End Using
  Return bmp
End Function

Pass in a form reference, and you've got yourself a bitmap of the form's contents. You could do this in 2003, but it required an ugly call to the BitBlt API method (I borrowed and modified code from MSDN for this portion):

' One of the many constants that modify
' the behavior of the BitBlt API:
Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source

Private Declare Function BitBlt _
 Lib "gdi32" Alias "BitBlt" _
 (ByVal hDestDC As IntPtr, _
 ByVal x As Integer, ByVal y As Integer, _
 ByVal nWidth As Integer, ByVal nHeight As Integer, _
 ByVal hSrcDC As IntPtr, _
 ByVal xSrc As Integer, ByVal ySrc As Integer, _
 ByVal dwRop As Integer) As Integer

Public Function GetFormImage(ByVal frm As Form) As Bitmap
  Dim bmp As Bitmap
  Dim formGraphics As Graphics
  Dim memoryGraphics As Graphics
  Dim dc1 As IntPtr
  Dim dc2 As IntPtr

  Try
    formGraphics = frm.CreateGraphics()

    ' Create a bitmap big enough to contain
    ' the entire form, and retrieve a Graphics
    ' object that can work with the bitmap:
    Dim sz As Size = frm.Size
    bmp = New Bitmap(sz.Width, sz.Height, formGraphics)
    memoryGraphics = Graphics.FromImage(bmp)

    ' Retrieve the two drawing context handles (HDCs)
    ' dc1 represents the form
    ' dc2 represents the new bitmap
    dc1 = formGraphics.GetHdc()
    dc2 = memoryGraphics.GetHdc()

    ' Copy the image to dc2,
    ' using rectange 0, 0, sz.Width, sz.Height
    ' from dc1
    ' copy from the upper-left corner
    BitBlt(dc2, _
       0, 0, _
       sz.Width, sz.Height, _
       dc1, _
       -1 * SystemInformation.FrameBorderSize.Width, _
       -1 * (SystemInformation.FrameBorderSize.Height + _
       SystemInformation.CaptionHeight), SRCCOPY)

  Catch ex As Exception
    MessageBox.Show(ex.Message)

  Finally
    If Not formGraphics Is Nothing Then
      formGraphics.ReleaseHdc(dc1)
      formGraphics.Dispose()
    End If
    If Not memoryGraphics Is Nothing Then
      memoryGraphics.ReleaseHdc(dc2)
      memoryGraphics.Dispose()
    End If
  End Try

  Return bmp
End Function

It's ugly. It's complex. But it works! If you need to create a screen dump of a form, either in 2003 or 2005, it's possible. Just takes a little digging...

Published Friday, December 16, 2005 7:01 PM by KenG

Comments

Monday, October 16, 2006 4:37 AM by Neil Turp

# re: Create Screen Dump of a Windows Form

thanks - very useful.  Saved me hours of digging out api code