Brian Julius
Brian Julius

Reputation: 11

How to print using multiple screenshots captured with copyfromscreen

I'm pretty new to C# but I finally have my first program up and running and I need to make it print. Its a window form with information and calculations on different tab controls, somewhat like Excel. The page that is currently being looked at prints fine with the copyfromscreen method, but I cannot get additional pages to print correctly. I have about 20 tabs I would like to be able to print at one time. I found a way to print the contents of controls into a textfile, but I would much prefer to be able to print what the form looks like. Thanks.

    Bitmap memoryImage;
    Bitmap memoryImage2;
    private void CaptureScreen()
    {

        Graphics myGraphics = this.CreateGraphics();
        Size s = tabControlMain.Size;
        s.Width = s.Width + 20;
        memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
        Graphics memoryGraphics = Graphics.FromImage(memoryImage);
        memoryGraphics.CopyFromScreen(this.Location.X+15, this.Location.Y+80, 0, 0, s);

        tabControlMain.SelectedIndex = 1;
        memoryImage2 = new Bitmap(s.Width, s.Height, myGraphics);
        Graphics memoryGraphics2 = Graphics.FromImage(memoryImage2);
        memoryGraphics2.CopyFromScreen(this.Location.X + 15, this.Location.Y + 80, 0, 0, s);


    }
    private void printDocumentReal_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        e.Graphics.DrawImage(memoryImage, 0, 0);
        e.Graphics.DrawImage(memoryImage2, 0, 550);

    }
    private void printToolStripButton_Click(object sender, EventArgs e)
    {
        CaptureScreen();
        printDocumentReal.Print();
    }

Upvotes: 1

Views: 1036

Answers (2)

Rami Yusf
Rami Yusf

Reputation: 3032

First, you should use PrintDocument and PrintPreviewDialog objects for print related tasks and an event handler for printing. Second, you need to preform some optimization for your code, here's the solution:

private void printToolStripButton_Click(object sender, EventArgs e)
    {
        PrintDocument document = new PrintDocument();
        document.PrintPage += new PrintPageEventHandler(document_PrintPage);
        PrintPreviewDialog preview = new PrintPreviewDialog() { Document = document };
        // you will be able to preview all pages before print it ;)
        try
        {
            preview.ShowDialog();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\nYou need to install a printer to preform print-related tasks!", "Print Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    Boolean firstPage = true;
    private void document_PrintPage(object sender, PrintPageEventArgs e)
    {
        if (firstPage)
        {
            tabControlMain.SelectTab(0);
            firstPage = false;
        }
        Graphics g = e.Graphics;
        TabPage tab = tabControlMain.SelectedTab;
        using (Bitmap img = new Bitmap(tab.Width, tab.Height))
        {
            tab.DrawToBitmap(img, tab.ClientRectangle);
            g.DrawImage(img, new Point(e.MarginBounds.X, e.MarginBounds.Y)); // MarginBounds means the margins of the page 
        }
        if (tabControlMain.SelectedIndex + 1 < tabControlMain.TabCount)
        {
            tabControlMain.SelectedIndex++;
            e.HasMorePages = true;//If you set e.HasMorePages to true, the Document object will call this event handler again to print the next page.
        }
        else
        { 
            e.HasMorePages = false;
            firstPage = true;
        } 
    }

I hope it's working fine with you And here's an additional one if you need to save all tabs as set of images on your hard disk:

    public void RenderAllTabs()
    {
        foreach (TabPage tab in tabControlMain.TabPages)
        {
            tabControlMain.SelectTab(tab);
            using (Bitmap img = new Bitmap(tab.Width, tab.Height))
            {
                tab.DrawToBitmap(img, tab.ClientRectangle);
                img.Save(string.Format(@"C:\Tabs\{0}.png", tab.Text));
            }
        }
    }

Upvotes: 1

King King
King King

Reputation: 63377

Try using DrawToBitmap method of TabPage instead:

private void CaptureScreen()
{
    memoryImage = new Bitmap(tabControlMain.SelectedTab.Width, tabControlMain.SelectedTab.Height);
    tabControlMain.SelectedTab.DrawToBitmap(memoryImage, tabControlMain.SelectedTab.ClientRectangle);
    tabControlMain.SelectedIndex = 1;
    memoryImage2 = new Bitmap(tabControlMain.SelectedTab.Width, tabControlMain.SelectedTab.Height);        
    tabControlMain.SelectedTab.DrawToBitmap(memoryImage2, tabControlMain.SelectedTab.ClientRectangle);
}

To get all the images of your TabPages, you can make a loop like this:

List<Bitmap> images = new List<Bitmap>();
private void CaptureScreen(){
   foreach(TabPage page in tabControlMain.TabPages){
      Bitmap bm = new Bitmap(page.Width, page.Height);
      tabControlMain.SelectedTab = page;
      page.DrawToBitmap(bm, page.ClientRectangle);
      images.Add(bm);
   }
}
//Then you can access the images of your TabPages in the list images
//the index of TabPage is corresponding to its image index in the list images

Upvotes: 0

Related Questions