在 C# 中打印 Windows 窗体

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13821715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:53:47  来源:igfitidea点击:

Print Windows form in c#

c#formsvisual-studio-2008

提问by Max

I am trying to print a form using this code:

我正在尝试使用以下代码打印表单:

private void btnPrint_Click(object sender, EventArgs e)
    {
        Graphics g1 = this.CreateGraphics();
        Image MyImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, g1);
        Graphics g2 = Graphics.FromImage(MyImage);
        IntPtr dc1 = g1.GetHdc();
        IntPtr dc2 = g2.GetHdc();
        BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);
        g1.ReleaseHdc(dc1);
        g2.ReleaseHdc(dc2);
        MyImage.Save(@"c:\PrintPage.jpg", ImageFormat.Jpeg);
        FileStream fileStream = new FileStream(@"c:\PrintPage.jpg", FileMode.Open, FileAccess.Read);
        StartPrint(fileStream, "Image");
        fileStream.Close();
        if (System.IO.File.Exists(@"c:\PrintPage.jpg"))
        {
            System.IO.File.Delete(@"c:\PrintPage.jpg");
        }
    }

But is gives me an error at: MyImage.Save.

但它给了我一个错误:MyImage.Save。

The error:

错误:

ExternalException was Unhandled: A generic error occurred in GDI+.

ExternalException 未处理:GDI+ 中发生一般错误。

Can someone give me a fix for this problem,and explain, why I'am getting this error?

有人可以解决这个问题,并解释一下,为什么我会收到这个错误?

Thanks in Advance!

提前致谢!

采纳答案by sanjeev

    private void btn_print_Click(object sender, EventArgs e)
    {
        CaptureScreen();
        printDocument1.Print();
        printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
    }

    Bitmap memoryImage;

    private void CaptureScreen()
    {
        Graphics myGraphics = this.CreateGraphics();
        Size s = this.Size;
        memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
        Graphics memoryGraphics = Graphics.FromImage(memoryImage);
        memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
    }


    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {

    }

    private void printDocument1_PrintPage_1(object sender, PrintPageEventArgs e)
    {
        e.Graphics.DrawImage(memoryImage, 0, 0);
    }

Add a print_document by dragging it from the toolbox to form. Execute this code, it will work fine.

通过将其从工具箱拖动到表单来添加一个 print_document。执行此代码,它将正常工作。

http://csharpprobsandsoln.blogspot.in/2013/04/print-windows-form-in-c.html

http://csharpprobsandsoln.blogspot.in/2013/04/print-windows-form-in-c.html

回答by toni robinson

Add:

添加:

using System.Drawing.Printing;

and in your code, add:

并在您的代码中添加:

PrintDocument printDocument1 = new PrintDocument();

More info here

更多信息在这里

回答by Sergey

I had the same task and I have created a class (like printable form). All you have to do is to inherit your Form from that class and call PrintForm(); method. Here is the class:

我有同样的任务,我创建了一个类(如可打印表单)。你所要做的就是从那个类继承你的 Form 并调用 PrintForm(); 方法。这是课程:

public class CustomForm : Form
{
    protected Bitmap _prnImage;
    protected PrintPreviewDialog _prnpreviewdlg = new PrintPreviewDialog();
    protected PrintDocument _printdoc = new PrintDocument();

    public CustomForm()
    {
        _printdoc.PrintPage += new PrintPageEventHandler(printdoc_PrintPage);
    }

    protected void PrintForm()
    {
        Form form = this;
        _prnImage = new Bitmap(form.Width, form.Height);
        form.DrawToBitmap(_prnImage, new Rectangle(0, 0, form.Width, form.Height));
        _printdoc.DefaultPageSettings.Landscape = true;
        _printdoc.DefaultPageSettings.Margins = new Margins(10, 10, 10, 10);
        _prnpreviewdlg.Document = _printdoc;
        _prnpreviewdlg.ShowDialog();
    }
    protected void printdoc_PrintPage(object sender, PrintPageEventArgs e)
    {
        Rectangle pagearea = e.PageBounds;
        e.Graphics.DrawImage(_prnImage, e.MarginBounds);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (_prnImage != null)
        {
            e.Graphics.DrawImage(_prnImage, 0, 0);
            base.OnPaint(e);
        }
    }
}

I understand that interface is a more academic and correct way to do that but in my particular case that solution satisfied me.

我知道接口是一种更加学术和正确的方式来做到这一点,但在我的特殊情况下,该解决方案让我满意。