I have seen many examples of how to do this when Googling, and some work better than others. Some of the issues I've seen include not taking into account multiple monitors ... it only works with your main laptop/tablet screen, or the image ends up spanning your laptop screen plus all of your monitors (I use two external monitors ... imagine three screens crammed onto one page)! Not exactly what you're looking for, is it?
After a bit of trial-and-error, cobbling together bits and pieces from various other sources that I've found with Google, I've come up with this. It works pretty well, I think. Call this PrintForm() method from a button click:
public void PrintScreen()
{
System.Drawing.Printing.PrintDocument oDoc = new System.Drawing.Printing.PrintDocument();
oDoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(oDoc_PrintPage);
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new System.Drawing.Printing.PrinterSettings();
pd.Document = oDoc;
oDoc.DefaultPageSettings.Landscape = true;
// print like this:
//if (pd.ShowDialog() == DialogResult.OK)
//{
// oDoc.Print();
//}
// for now, let's just use the print preview to demonstrate
PrintPreviewDialog ppd = new PrintPreviewDialog();
ppd.Document = oDoc;
ppd.ShowDialog();
}
The PrintPage EventHandler gets called for both the Print and the PrintPreviewDialog, so all the necessary code is in this event handler:
private void oDoc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
// First, let's get the image of this running Form that we want to print
Bitmap formBitmap = new Bitmap(this.Width, this.Height);
this.DrawToBitmap(formBitmap, new Rectangle(0, 0, this.Width, this.Height));
// for clearer images
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// this bit of code is needed to figure out if we need to scale the bitmap to fit the page
// (there is an implicit conversion from int to float)
float neededWidth = this.Width;
float neededHeight = this.Height;
float availableWidth = e.PageBounds.Width;
float availableHeight = e.PageBounds.Height;
double neededRatio = neededWidth / neededHeight;
double availableRatio = availableWidth / availableHeight;
float fitRatio = 1;
if (neededRatio >= availableRatio)
fitRatio = availableWidth / neededWidth;
else
fitRatio = availableHeight / neededHeight;
// The Min size needs to be converted to int for the DrawImage() method.
int newWidth = Convert.ToInt32(Math.Min(neededWidth * fitRatio, availableWidth));
int newHeight = Convert.ToInt32(Math.Min(neededHeight * fitRatio, availableHeight));
e.Graphics.DrawImage(formBitmap, 0, 0, newWidth, newHeight);
}
Have fun and Happy Coding! =0)
No comments:
Post a Comment