2012-11-13 37 views
6

Tôi đã cố gắng in nội dung của RichTextBox và có quá nhiều lỗi nếu tôi in bằng máy in. Nhưng khi tôi đang in tệp XPS (thông qua máy in XPS trong cửa sổ) và sau đó in tệp này vào máy in thì tất cả đều ổn.In tệp XPS và sau đó in nó vào máy in

Tôi có thể làm tất cả những việc này theo cách lập trình không?

Đây là phương pháp in ấn của tôi:

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

Bạn đã bao giờ tìm thấy giải pháp cho điều này chưa? Tôi đang tìm cách làm điều tương tự. –

+0

Thật không may là không. Nhiệm vụ này có ưu tiên thấp bây giờ cho tôi. –

+0

Tôi cũng muốn một giải pháp cho điều này. – Jeff

Trả lời

1

Tôi đã có một vấn đề như thế này, và kết thúc làm cho một tập tin .XPS và sau đó gửi đến máy in.

Từ câu hỏi của bạn, có vẻ như bạn đã có quá trình "in" tệp xps xuống, điều này là tốt vì tôi không biết gì về quá trình in hộp văn bản có định dạng sang tệp xps. Trong scenaria của tôi, tôi cần in một dokument mà không sử dụng ms office, vì vậy tôi đã tạo một tệp XPS, chỉnh sửa nó trong mã, và sau đó gửi nó đến máy in.

Đây là mã tôi sử dụng để gửi xps-file trực tiếp đến máy in:

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

Cũng nên nhớ rằng đối với mã này để làm việc bạn cần phải thêm tham chiếu đến System.Printing VÀ "ReachFramework". Mất nhiều thời gian hơn tôi quan tâm để nhớ để tìm hiểu lý do tại sao tôi không thể truy cập vào printjob.

Hầu hết các máy in phải hỗ trợ điều này theo kinh nghiệm của tôi. Những cái phổ biến và thậm chí nó hoạt động trên "máy in mã vạch" lẻ tại bộ phận lưu trữ của chúng tôi.