VB.Net Save or Print Panel Contents

I've spent ages trying to find a way of printing (or saving) the graphics contained within a panel on a VB.Net form. This is easy if the panel is all in view, but the problem comes when the panel is too big to fit the screen, or it is partly scrolled out of view.

Here, I'm trying to save the contents of panel pnlDetail to file c:\out.bmp.

You might find problems with this, but it's an example that works for me, so it might save you time trying to get it to work. It seems that loads of people are having trouble printing the contents of a panel partly obscured of off the screen.

Hope this is of some use.


    Declare Auto Function SendMessage Lib "user32" ( _
            ByVal hWnd As IntPtr, _
            ByVal Msg As Integer, _
            ByVal wParam As IntPtr, _
            ByVal lParam As Integer) As Integer

    Private Enum EDrawingOptions As Integer
        PRF_CHECKVISIBLE = &H1
        PRF_NONCLIENT = &H2
        PRF_CLIENT = &H4
        PRF_ERASEBKGND = &H8
        PRF_CHILDREN = &H10
        PRF_OWNED = &H20
    End Enum

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        Const WM_PRINT As Integer = &H317

        Dim myBmp As Bitmap
        Dim myGraphics As Graphics
        Dim hdc As System.IntPtr

        myBmp = New Bitmap( _
            pnlDetail.DisplayRectangle.Width, _
            pnlDetail.DisplayRectangle.Height)

        myGraphics = Graphics.FromImage(myBmp)

        hdc = myGraphics.GetHdc

        Call SendMessage(pnlDetail.Handle, WM_PRINT, hdc, _
            EDrawingOptions.PRF_CHILDREN Or _
            EDrawingOptions.PRF_CLIENT Or _
            EDrawingOptions.PRF_NONCLIENT Or _
            EDrawingOptions.PRF_OWNED)

        myGraphics.ReleaseHdc(hdc)

        myBmp.Save("c:\out.bmp")

        myGraphics.Dispose()
        myGraphics = Nothing

        myBmp = Nothing

    End Sub
		

Just to prove it works!

Save Panel Example