print the panel control

  • Thread starter Thread starter Kevin
  • Start date Start date
K

Kevin

I would like to print the panel control. The panel
controls contains images and lables.

If i can capture as image i can use it for other purposes
like Zooming etcc..

Any body have any idea ,,, ?
 
Hi Kevin,

There are two methods that I know for capturing the graphics of a Control.
Both have been included below (for future reference), but only the first will
work for panels.

The first one takes a copy of the Control's surface as it exists. This
means that the Control must be visible and with no other windows on top.

The other one works by fooling the Control into doing its Paint onto a
supplied Bitmap. This works fine for many Controls but not for Panels or
GroupBoxes (and probably not for other container Controls).

In use:
Dim bmpPanel As Bitmap = CaptureControl (pnlSomething)

Regards,
Fergus

<code>
'===============================================================
Public Const SRCCOPY As Integer = &HCC0020

Public Declare Function BitBlt Lib "gdi32" ( _
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 CaptureControl(ByVal c As Control) As Bitmap

Dim bmp As Bitmap
Dim gDest, gSource As Graphics
Dim hdcSource, hdcDest As IntPtr

bmp = New Bitmap(c.Width, c.Height)

gSource = c.CreateGraphics
Try
gDest = Graphics.FromImage(bmp)
Try
hdcSource = gSource.GetHdc
Try
hdcDest = gDest.GetHdc
Try
BitBlt( _
hdcDest, 0, 0, _
c.Width, c.Height, _
hdcSource, 0, 0, SRCCOPY _
)
Finally
gDest.ReleaseHdc(hdcDest)
End Try
Finally
gSource.ReleaseHdc(hdcSource)
End Try
Finally
gDest.Dispose()
End Try
Finally
gSource.Dispose()
End Try

Return bmp
End Function

'===============================================================
Public Function PaintControlToBitmap (oControl As Control) As Bitmap
Dim OnPaintMethod As MethodInfo
OnPaintMethod = oControl.GetType.GetMethod ("OnPaint", _
BindingFlags.Instance Or BindingFlags.NonPublic)

If Not OnPaintMethod Is Nothing Then
Dim bmpControl As New Bitmap (oControl.Width, oControl.Height)
Dim gr As Graphics = Graphics.FromImage (bmpControl)
Dim PaintEventArgs As New PaintEventArgs (gr, _
New Rectangle(0, 0, oControl.Width, oControl.Height))
OnPaintMethod.Invoke(oControl, New Object() {PaintEventArgs})
gr.Dispose
Return bmpControl
End If
End Function

'===============================================================
Public Sub CopyGraphics (gSource As Graphics, gDest As Graphics, _
Width As Integer, Height As
Integer)

Dim hdcSource, hdcDest As IntPtr

hdcSource = gSource.GetHdc
Try
hdcDest = gDest.GetHdc
Try
BitBlt( _
gDest.GetHdc, 0, 0, _
Width, Height, _
gSource.GetHdc, 0, 0, SRCCOPY _
)
Finally
gDest.ReleaseHdc(hdcDest)
End Try
Finally
gSource.ReleaseHdc(hdcSource)
End Try
End Sub
</code>
 
Hello Fergus

I used the first one..

Dim bmpPanel As Bitmap = CaptureControl

It save a black image which has nothing in it.. can you
please suggest me.. what could be the problem
 
Hi Kevin,

Having tested the code before I posted it, and on several Controls - Panel
(filled), GroupBox (stuffed), RichTextBox, etc, I know that it works. **

The only conditions required are that the Control <must> be visible. If
<you> can see it then CaptureControl should see it too.If this is the case
then I'm not sure what to suggest, other than to send me the project.

If you need to send me the project, make a copy and cut it down to the
bare minimum (just one form preferably) and zip it without any bin or obj
directories.

Regards,
Fergus

** Famous last words?? I shall test with a new project, using the code as I
gave it to you.
 
It works fine.. Sorry for the confussion .. I put wrong
destination and source in the BitBlt function

I've another problem.. I need to print the entire
invisible area of the panel also.. Is there any way i can
do that...

Thanks a lot
 
Hi Kev,

No worries, I was expecting/hoping that it would be some little glitch.

What do you mean by the invisible area of a Panel?

Regards,
Fergus
 
My control height is more than the forms height. SO I use
form's scrollbar to view the rest of it.

Now with your help .. I can capture the image of visible
portion of the pannel. But my panel has more images which
can be viewable only through the form's scrollbar.

FYI: I use the panel to allow the user to desgin their
layout and save it in the database. I keep objects like
picturebox and lable to acheive this... I should allow
them to print their layout. Another requirement is they
should ZOOM also. I don't know how to provide this, So I
thought of capturing the entire panel so that that they
can print and zoom what they want..

Your help in this matter is really appreciated
 
Hi Kev,

This problem has been a bane for many people, in this and other
newsgroups. It seems like such a reasonable request.

The problem with methods like the one in CaptureControl is that, as far as
I understand it, they are working with screen bitmaps, or at least what is
destined to go to the screen. Thus anything that is out of sight will not be
rendered - namely stuff that is underneath another window, scrolled out of
sight (like your panel) or on a part of a virtual desktop that isn't on the
monitor (we tried that as a solution, but no joy). This makes sense but isn't
useful when the missing bit is what you want.

One workaround for your case is simply to scroll the Panel to the top,
capture it, then scroll it down, capture the remainder, sew them together and
then scroll hte Panel to where the User left it. It will appear as a flicker
to the user, I suppose. (You might need to add a DoEvents or Panel.Refresh to
make it work).

That word zoom got me going there. Our very own Cor had a query about
working with photos a few days ago. I wrote him a demo which does cropping and
zooming. Basically there's a thumbnail view and a selection rectangle drawn on
it. Whatever's in the rectangle will be copied to the main picture (thus the
cropping) and the rectangle can be dragged around as required. The zooming
part is handled by shrinking and enlarging the selection rectangle (and then
moving it around to centre it nicely).

It seems to me that you might be able to bend that technique to suit your
purposes. But instead of cropping a bitmap, you use the zoom to scale the
Controls. There's an attachment in Cor's query (Topic: newbie question about
graphics, dated 28th Oct) which contains the code. It might give you some
ideas. (It was a single night's work so it works but the code is fairly raw).

I'd be interested to discuss this further. I'd be especially keen to see
it in action, if you wouldn't mind. A project sent to my email address would
be welcomed (no obj or bin).

Regards,
Fergus
 
Back
Top