Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print into XPS-file and then print it to printer

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();
    }
like image 541
Dmitry Belov Avatar asked Nov 13 '12 12:11

Dmitry Belov


People also ask

Can XPS document be printed?

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.

How do I print a PDF in XPS?

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.

How do I print directly from a file?

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.

How do I convert XPS to Word or PDF?

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.


1 Answers

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.

like image 85
Kaspar Kjeldsen Avatar answered Sep 22 '22 06:09

Kaspar Kjeldsen