2012-11-13 15 views
6

Ho provato a stampare il contenuto di RichTextBox e ci sono troppi bug se si stampa su stampante. Ma quando sto stampando su file XPS (tramite XPS-printer in windows) e poi stampo questo file su stampante tutto va bene.Stampare nel file XPS e quindi stamparlo sulla stampante

Quindi posso eseguire tutte queste operazioni a livello di codice?

Ecco il mio metodo di stampa:

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

Hai mai trovato una soluzione per questo? Sto cercando di fare la stessa cosa. –

+0

Purtroppo no. Questo compito ha ora bassa priorità per me. –

+0

Vorrei una soluzione anche a questo. – Jeff

risposta

1

Ho avuto un problema come questo, e ha finito per fare un file con estensione XPS e quindi l'invio che per la stampante.

Dalla tua domanda, sembra che tu abbia già in corso il processo di "stampa" sul file xps, il che è positivo poiché non so nulla del processo di stampa della casella di testo RTF nel file xps. Nei miei scenari avevo bisogno di stampare un documento senza usare ms office, quindi ho finito per creare un file XPS, modificarlo in codice e quindi inviarlo alla stampante.

Questo è il codice che uso per inviare il XPS file direttamente alla stampante:

LocalPrintServer localPrintServer = new LocalPrintServer(); 
var queue = localPrintServer.GetPrintQueue("NameOfPrinter"); 
PrintSystemJobInfo xpsPrintJob = queue.AddJob("name of print job", "my/xps/path.xps",false); 

Ricordate anche che per questo codice per lavorare è necessario aggiungere i riferimenti a System.Printing AND "ReachFramework". Mi ci è voluto più tempo di quanto mi preoccupassi di ricordare per scoprire perché non potevo accedere al lavoro di stampa.

La maggior parte delle stampanti dovrebbe supportarlo nella mia esperienza. Quelli comuni e funziona persino con la strana "stampante di codici a barre" presso il nostro magazzino.