Print Panel

A

Alberto

I have to print the content of a panel but I have two problems. The code
I've written is this:

Bitmap imagen = null;
private void btnImprimir_Click(object sender, EventArgs e)

{

PrintPreviewDialog ppd = new PrintPreviewDialog();

PrintDocument doc = new PrintDocument();

doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);

ppd.Document = doc;

CapturaImagen();

if (ppd.ShowDialog() == DialogResult.OK)

doc.Print();

}

void doc_PrintPage(object sender, PrintPageEventArgs e)

{

e.Graphics.DrawImage(imagen, 0, 0);

}

private void CapturaImagen()

{

int width = rbolActual.Width;

int height = rbolActual.Height;

imagen = new Bitmap(width, height);

Rectangle rec = new Rectangle(0, 0, width, height);

rbolActual.DrawToBitmap(imagen, rec);

}



1) The size of the image use to be 1008 x 626 pixels so it's larger than a
normal paper (A4).

2) I'd like to see a print preview dialog so that I could say the number of
copies and select the printer but I don't know how to do it.

Thank you very much.
 
P

Peter Duniho

Alberto said:
[...]
1) The size of the image use to be 1008 x 626 pixels so it's larger than a
normal paper (A4).

Actually, the number of pixels isn't strictly what's important. It's
the number of pixels in combination with the resolution specified in the
image, as well as the scaling applied to the Graphics instance when the
image is drawn.

In your case, it seems to me that you should be able to just draw the
image using a DrawImage() overload in which you specify the exact
destination rectangle, rather than relying on the image's own metrics.
Just obtain the destination rectangle from the page dimensions itself
(optionally preserving aspect ratio by scaling one dimension or the
other to fit).
2) I'd like to see a print preview dialog so that I could say the number of
copies and select the printer but I don't know how to do it.

Looking at your code, you seem to already have a print preview dialog.
As far as allowing the user to specify the printer, pages, etc. wouldn't
the PrintDialog accomplish that?

http://msdn.microsoft.com/en-us/library/system.windows.forms.printdialog.aspx

By the way, DrawToBitmap() may not do what you expect. In particular,
it will only draw the parts of the control that is actually visible on
the screen. It's actually kind of tricky to get an exact image of a
control saved to a bitmap for printing, and in fact I'm not aware of a
100% reliable way to do it (but if you know enough about the specific
control, such as whether it handles the WM_PRINT message and what
children are in it, you can get close).

Pete
 
A

Alberto

How can I find out the size of the page where I'm going to print the
graphic?
Thank you.
Peter Duniho said:
Alberto said:
[...]
1) The size of the image use to be 1008 x 626 pixels so it's larger than
a normal paper (A4).

Actually, the number of pixels isn't strictly what's important. It's the
number of pixels in combination with the resolution specified in the
image, as well as the scaling applied to the Graphics instance when the
image is drawn.

In your case, it seems to me that you should be able to just draw the
image using a DrawImage() overload in which you specify the exact
destination rectangle, rather than relying on the image's own metrics.
Just obtain the destination rectangle from the page dimensions itself
(optionally preserving aspect ratio by scaling one dimension or the other
to fit).
2) I'd like to see a print preview dialog so that I could say the number
of copies and select the printer but I don't know how to do it.

Looking at your code, you seem to already have a print preview dialog. As
far as allowing the user to specify the printer, pages, etc. wouldn't the
PrintDialog accomplish that?

http://msdn.microsoft.com/en-us/library/system.windows.forms.printdialog.aspx

By the way, DrawToBitmap() may not do what you expect. In particular, it
will only draw the parts of the control that is actually visible on the
screen. It's actually kind of tricky to get an exact image of a control
saved to a bitmap for printing, and in fact I'm not aware of a 100%
reliable way to do it (but if you know enough about the specific control,
such as whether it handles the WM_PRINT message and what children are in
it, you can get close).

Pete
 
A

Alberto

I'm using this overload of the DrawImage:

e.Graphics.DrawImage(imagen,0,0,
doc.PrinterSettings.DefaultPageSettings.Bounds.Width, imagen.Height);

The problem is that there is that It isn't printing all the image. It cuts a
bit on the right side.
Thank you.
Peter Duniho said:
Alberto said:
[...]
1) The size of the image use to be 1008 x 626 pixels so it's larger than
a normal paper (A4).

Actually, the number of pixels isn't strictly what's important. It's the
number of pixels in combination with the resolution specified in the
image, as well as the scaling applied to the Graphics instance when the
image is drawn.

In your case, it seems to me that you should be able to just draw the
image using a DrawImage() overload in which you specify the exact
destination rectangle, rather than relying on the image's own metrics.
Just obtain the destination rectangle from the page dimensions itself
(optionally preserving aspect ratio by scaling one dimension or the other
to fit).
2) I'd like to see a print preview dialog so that I could say the number
of copies and select the printer but I don't know how to do it.

Looking at your code, you seem to already have a print preview dialog. As
far as allowing the user to specify the printer, pages, etc. wouldn't the
PrintDialog accomplish that?

http://msdn.microsoft.com/en-us/library/system.windows.forms.printdialog.aspx

By the way, DrawToBitmap() may not do what you expect. In particular, it
will only draw the parts of the control that is actually visible on the
screen. It's actually kind of tricky to get an exact image of a control
saved to a bitmap for printing, and in fact I'm not aware of a 100%
reliable way to do it (but if you know enough about the specific control,
such as whether it handles the WM_PRINT message and what children are in
it, you can get close).

Pete
 
P

Peter Duniho

Alberto said:
I'm using this overload of the DrawImage:

e.Graphics.DrawImage(imagen,0,0,
doc.PrinterSettings.DefaultPageSettings.Bounds.Width, imagen.Height);

Why do you use the image for one dimension (height) but the page for the
other (the width)? That doesn't seem like it would produce any useful
results at all, as there is no well-defined relationship between the
dimensions of the two objects.
The problem is that there is that It isn't printing all the image. It cuts a
bit on the right side.

Printers have the page size, and the printable area. The printable area
is some subset of the page size, as it's the part of the page excluding
that area the printer can't print on because of page feed or other
mechanical issues.

You could get this from the PrintableArea property of the PageSettings
object you get from the DefaultPageSettings property. But, the user can
change the page settings for the print job (if you provide the UI for
that, which you've specifically asked about doing so presumably you
will), and then the information you get from the default settings won't
be applicable.

Instead, you should be looking at the PageSettings object passed via the
PrintPageEventArgs in your PrintPage event handler. That will give you
the page information specific to the page you're actually printing. You
can use the PrintableArea from that to determine the area to print, or
you can give the user more control and use the margin information in the
PageSettings object instead, or you could even take the intersection of
the rectangle defined by both pieces of information, to give the user
control but also ensure you never print outside the printable area.

But accounting for the printable area will only address the part of the
image that's cut off on the right. You still need to fix the height
you're using for drawing the image too.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top