【问题标题】:How to print using multiple screenshots captured with copyfromscreen如何使用通过 copyfromscreen 捕获的多个屏幕截图进行打印
【发布时间】:2013-08-18 04:30:23
【问题描述】:

我对 C# 还很陌生,但我终于启动并运行了我的第一个程序,我需要将其打印出来。它是一个窗口表单,在不同的选项卡控件上包含信息和计算,有点像 Excel。使用 copyfromscreen 方法可以正常打印当前正在查看的页面,但我无法正确打印其他页面。我想一次打印大约 20 个标签。我找到了一种将控件内容打印到文本文件中的方法,但我更希望能够打印表单的样子。谢谢。

    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();
    }

【问题讨论】:

  • 只捕获TabPage 好吗?或者你需要捕获整个TabControl
  • 是的,我只需要能够打印 20 个左右的 TabPages 中的每一个
  • 使用 PrintPageEventArgs.HasMorePages 属性来打印多个页面已在有关 PrintDocument 的 MSDN 库文章中得到了很好的介绍。只需计算页面,选择正确的图形来绘制。您还需要 BeginPrint 事件来重置计数器。请注意屏幕截图很难看,打印机的分辨率远高于屏幕的分辨率,因此每个屏幕像素都会在纸上变成一个 6x6 的斑点。

标签: c# winforms printing


【解决方案1】:

首先,您应该将PrintDocumentPrintPreviewDialog 对象用于打印相关任务并使用事件处理程序进行打印。 其次,您需要对您的代码进行一些优化,解决方案如下:

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;
        } 
    }

我希望它与您一起工作正常如果您需要将所有选项卡保存为硬盘上的一组图像,这里还有一个:

    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));
            }
        }
    }

【讨论】:

  • 您需要 BeginPrint 才能将 firstPage 设置回 true。
【解决方案2】:

尝试改用TabPageDrawToBitmap 方法:

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);
}

要获取TabPages 的所有图像,您可以这样循环:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2015-04-06
    • 1970-01-01
    相关资源
    最近更新 更多