问题 C#打印(RichTextBox)


我想打印我的RichTextBox(eintragRichTextBox)的内容 我现在有这个代码:

private void druckenPictureBox_Click(object sender, EventArgs e)
{
    PrintDialog printDialog = new PrintDialog();
    PrintDocument documentToPrint = new PrintDocument();
    printDialog.Document = documentToPrint;

    if (printDialog.ShowDialog() == DialogResult.OK)
    {
        StringReader reader = new StringReader(eintragRichTextBox.Text);
        documentToPrint.Print();
        documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
    }
}

private void DocumentToPrint_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    StringReader reader = new StringReader(eintragRichTextBox.Text);
    float LinesPerPage = 0;
    float YPosition = 0;
    int Count = 0;
    float LeftMargin = e.MarginBounds.Left;
    float TopMargin = e.MarginBounds.Top;
    string Line = null;
    Font PrintFont = this.eintragRichTextBox.Font;
    SolidBrush PrintBrush = new SolidBrush(Color.Black);

    LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);

    while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
    {
        YPosition = TopMargin + (Count * PrintFont.GetHeight(e.Graphics));
        e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat());
        Count++;
    }

    if (Line != null)
    {
        e.HasMorePages = true;
    }
    else
    {
        e.HasMorePages = false;
    }
    PrintBrush.Dispose();
}

但它总是打印我一个空白的网站:( ..任何人的想法,为什么它不工作? 或者有一个更好的代码/想法如何实现打印?

编辑: 看看答案


7303
2017-09-13 09:49


起源

你为什么要在documentToPrint.Print()之前创建这个:“StringReader reader ...”?我想你不需要它。麻生太郎,调试时会发生什么? - Davide Piras
我还没有发现你的问题,但有一件事是,如果你的RTB有足够的文本来填充多个页面,你会发现它打印了无数页面。您需要在PrintPage事件范围之外声明您的Reader,Count和Line值...您还需要进行一些调试,添加一些断点并查看正在设置的值是什么,哪些不是 - musefan
support.microsoft.com/kb/812425 - Hans Passant
嗯也许代码工作,但它可能是,我没有足够的墨水..将尽快检查 - eMi
嗯不,有足够的墨水,我可以用文字打印文字文件..而我的RTB没有很多文字,有时只有一个短语..而且调试不起作用,不知道为什么.. - eMi


答案:


得到它了..

在这个地方:

if (printDialog.ShowDialog() == DialogResult.OK)
{
    StringReader reader = new StringReader(eintragRichTextBox.Text);
    documentToPrint.Print();
    documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
}

我改为:

if (printDialog.ShowDialog() == DialogResult.OK)
{
    StringReader reader = new StringReader(eintragRichTextBox.Text);
    documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
    documentToPrint.Print();    
}

现在它工作正常..

此外,如果有人需要打印RichTextBox的内容,您可以使用我的代码..


5
2017-11-09 15:21



这不会打印带有样式的文档,打印长文本需要很长时间! - Alex Jolig
我4年前写了这段代码,然后目标不是用风格打印它。无论如何,感谢您在答案中提供新的变体。 - eMi


我试过了 如何打印RichTextBox控件的内容 它就像一个魅力。

你只需要创建一个自定义 RichTextBox 然后它将如此快速地打印整个文本,并保持在纸上的风格!

创建自定义的代码 RichTextBox

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Printing;

namespace RichTextBoxPrintCtrl
{
    public class RichTextBoxPrintCtrl:RichTextBox
    {
        //Convert the unit used by the .NET framework (1/100 inch) 
        //and the unit used by Win32 API calls (twips 1/1440 inch)
        private const double anInch = 14.4;

        [StructLayout(LayoutKind.Sequential)] 
            private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
            private struct CHARRANGE
        {
            public int cpMin;         //First character of range (0 for start of doc)
            public int cpMax;           //Last character of range (-1 for end of doc)
        }

        [StructLayout(LayoutKind.Sequential)]
            private struct FORMATRANGE
        {
            public IntPtr hdc;             //Actual DC to draw on
            public IntPtr hdcTarget;       //Target DC for determining text formatting
            public RECT rc;                //Region of the DC to draw to (in twips)
            public RECT rcPage;            //Region of the whole DC (page size) (in twips)
            public CHARRANGE chrg;         //Range of text to draw (see earlier declaration)
        }

        private const int WM_USER  = 0x0400;
        private const int EM_FORMATRANGE  = WM_USER + 57;

        [DllImport("USER32.dll")]
        private static extern IntPtr SendMessage (IntPtr hWnd , int msg , IntPtr wp, IntPtr lp); 

        // Render the contents of the RichTextBox for printing
        //  Return the last character printed + 1 (printing start from this point for next page)
        public int Print( int charFrom, int charTo,PrintPageEventArgs e)
        {
            //Calculate the area to render and print
            RECT rectToPrint; 
            rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
            rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
            rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
            rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);

            //Calculate the size of the page
            RECT rectPage; 
            rectPage.Top = (int)(e.PageBounds.Top * anInch);
            rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
            rectPage.Left = (int)(e.PageBounds.Left * anInch);
            rectPage.Right = (int)(e.PageBounds.Right * anInch);

            IntPtr hdc = e.Graphics.GetHdc();

            FORMATRANGE fmtRange;
            fmtRange.chrg.cpMax = charTo;               //Indicate character from to character to 
            fmtRange.chrg.cpMin = charFrom;
            fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
            fmtRange.hdcTarget = hdc;              //Point at printer hDC
            fmtRange.rc = rectToPrint;             //Indicate the area on page to print
            fmtRange.rcPage = rectPage;            //Indicate size of page

            IntPtr res = IntPtr.Zero;

            IntPtr wparam = IntPtr.Zero;
            wparam = new IntPtr(1);

            //Get the pointer to the FORMATRANGE structure in memory
            IntPtr lparam= IntPtr.Zero;
            lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
            Marshal.StructureToPtr(fmtRange, lparam, false);

            //Send the rendered data for printing 
            res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);

            //Free the block of memory allocated
            Marshal.FreeCoTaskMem(lparam);

            //Release the device context handle obtained by a previous call
            e.Graphics.ReleaseHdc(hdc);

            //Return last + 1 character printer
            return res.ToInt32();
        }

    }
}

主要来源包括 PrintDialog, PrintPreviewDialog, PrintDocument, and PageSetupDialog,但只有一个工作正常 PrintDocument 控制。所以我删除了一些额外的代码只是为了缩短有用的部分。但如果您对使用它们感兴趣,可以在链接页面中找到完整代码。

    private PrintDocument _printDocument = new PrintDocument();
    private int _checkPrint;
    public Form1()
    {
        InitializeComponent();
        _printDocument.BeginPrint += _printDocument_BeginPrint;
        _printDocument.PrintPage += _printDocument_PrintPage;
    }

    private void btnPrint_Click(object sender, EventArgs e)
    {
        PrintDialog printDialog=new PrintDialog();
        if (printDialog.ShowDialog() == DialogResult.OK)
            _printDocument.Print();
    }

    private void _printDocument_PrintPage(object sender, PrintPageEventArgs e)
    {
        // Print the content of RichTextBox. Store the last character printed.
        _checkPrint = rchEditor.Print(_checkPrint, rchEditor.TextLength, e);

        // Check for more pages
        e.HasMorePages = _checkPrint < rchEditor.TextLength;
    }

    private void _printDocument_BeginPrint(object sender, PrintEventArgs e)
    {
        _checkPrint = 0;
    }

5
2017-10-04 10:25





看来你的代码有问题,它只重新打印第一页因为

StringReader reader = new StringReader(eintragRichTextBox.Text);

在你的 DocumentToPrint_PrintPage() 


0
2018-05-02 22:08





用那个!

StringReader reader;
        int prov = 0;

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


            if (prov == 0)
            {
                prov = 1;
                reader = new StringReader(eintragRichTextBox.Text);
            }
float LinesPerPage = 0;
            float YPosition = 0;
            int Count = 0;
            float LeftMargin = e.MarginBounds.Left;
            float TopMargin = e.MarginBounds.Top;
            string Line = null;

....


0
2018-05-31 19:12