I've tried to print content of RichTextBox and there are too many bugs if I print to printer. But when I'm printing to XPS-file (through XPS-printer in windows) and then printing this file to printer all is ok.
So can I do all these things programmatically?
Here is my printing method:
public int PrintRotate(bool rotate, PrintPageEventArgs e, int charFrom, int charTo)
{
//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
SetGraphicsMode(fmtRange.hdc, GM_ADVANCED);
XFORM par = new XFORM();
par = new XFORM();
par.eM11 = 1;
par.eM12 = 0;
par.eM21 = 0;
par.eM22 = 1;
par.eDx = -e.PageSettings.Margins.Left / 100 * e.PageSettings.PrinterResolution.X;
par.eDy = -e.PageSettings.Margins.Top / 100 * e.PageSettings.PrinterResolution.Y;
ModifyWorldTransform(fmtRange.hdc, ref par, MWT_LEFTMULTIPLY);
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();
}
If you create an XPS file, but don't have an app to save or store the contents, you can use the Microsoft XPS Document Writer printer to save all content of the XPS file. Microsoft XPS Document Writer comes pre-installed on Windows 10 and Windows 11, just press Ctrl + P to print/save an XPS file.
Click the Print icon or Select File –> Print. The Print window will appear. In the Printer drop-down box, select Microsoft XPS Document Writer. Then click Print.
Open the document or file you want to print. In the top portion of the program window or browser you're using, open the file menu by clicking File and then Print from the drop-down menu.
Browse and select the XPS file you want to view and click Open. After the XPS file loads into your drive, right-click it to Preview. From the Preview screen, click on the Printer icon in the top right of the screen. Under Destination, choose Save as PDF or Save to Google Drive to create a PDF version.
I've had a problem like this, and ended up making an .XPS file and then sending that to the printer.
From your question, it sounds like you already have the process of "printing" to the xps file down, which is good since I don't know anything about the process of printing the rich text box to the xps file. In my scenaria I needed to print a dokument without using ms office, so I ended up making a XPS file, edit it in code, and then send it to the printer.
This is the code I use to send the xps-file directly to the printer:
LocalPrintServer localPrintServer = new LocalPrintServer();
var queue = localPrintServer.GetPrintQueue("NameOfPrinter");
PrintSystemJobInfo xpsPrintJob = queue.AddJob("name of print job", "my/xps/path.xps",false);
Also remember that for this code to work you need to add references to System.Printing AND "ReachFramework". Took me longer than I care to remember to find out why I couldn't access the printjob.
Most printers should support this in my experience. The common ones and it even works on the odd "barcode-printer" at our storage-department.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With