我想将格式框内容与格式打印到任何设备上下文,例如我想在面板上打印或与实际打印设备关联的任何其他控件。
我通过从自定义设计的表单中绘制一些内容来使用面板模拟打印预览,富文本内容是该表单的内容之一
有没有解决这个问题的最佳解决方案?
答案 0 :(得分:0)
下面是将rtf控件的内容打印到打印机的代码。我可以很容易地适应任何旧的直流印刷。语言是强大的,但可以很容易地翻译成C语言,pascal语言或其他语言:
SUB PrintRichTextBox ( hWnd as LONG, hInst as LONG, rtfEdit as LONG, LM as Single, _
RM as Single, TM as Single, BM as Single )
'
' Purpose:
' Prints the contents of an RTF text box given it's handle, the
' calling program's handle(s), and the page margins.
'
' Parameters:
' hWnd = Parent window (used for print common dlg)
' hInst = Instance of calling program
' rtfEdit = Handle of rich edit control
' LM = Left Margin in inches
' RM = Right Margin in inches
' TM = Top Margin in inches
' BM = Bottom Margin in inches
'
Dim fr as FORMATRANGE
Dim rDocInfo as DOCINFO
Dim iTextOut as LONG
Dim iTextAmt as LONG
Dim pd as PRINTDLGAPI
Dim zString as ASCIIZ * 200
Dim iWidthTwips&
Dim iHeightTwips&
'- Setup the print common dialog
pd.lStructSize = len(pd)
pd.hwndOwner = hWnd
pd.hDevMode = %NULL
pd.hDevNames = %NULL
pd.nFromPage = 0
pd.nToPage = 0
pd.nMinPage = 0
pd.nMaxPage = 0
pd.nCopies = 0
pd.hInstance = hInst
pd.Flags = %PD_RETURNDC or %PD_NOPAGENUMS or %PD_PRINTSETUP
pd.lpfnSetupHook = %NULL
pd.lpPrintSetupTemplateName = %NULL
pd.lpfnPrintHook = %NULL
pd.lpPrintTemplateName = %NULL
if PrintDlg(pd) then
SetCursor LoadCursor( %NULL, BYVAL %IDC_WAIT )
'- Fill format range structure
'
' NOTE:
' This gave me fits. I was looking at the book from
' Microsoft Press called Programming the Windows 95
' Iterface. It said (via example) that the
' Rectagle was defined in Pixels. This didn't work right.
' The SDK, however, said the measurements needed to be
' in Twips! This seems to work fine.
'
'
fr.hdc = pd.hDC
fr.hdcTarget = pd.hDC
fr.chrg.cpMin = 0
fr.chrg.cpMax = -1
fr.rc.nTop = TM * 1440
fr.rcPage.nTop = fr.rc.nTop
fr.rc.nLeft = LM * 1440
fr.rcPage.nLeft = fr.rc.nLeft
'- Get page dimensions in Twips
iWidthTwips& = int((GetDeviceCaps(pd.hDC, %HORZRES) / GetDeviceCaps(pd.hDC, %LOGPIXELSX)) * 1440)
iHeightTwips& = int((GetDeviceCaps(pd.hDC, %VERTRES) / GetDeviceCaps(pd.hDC, %LOGPIXELSY)) * 1440)
fr.rc.nRight = iWidthTwips& - RM * 1440
fr.rcPage.nRight = fr.rc.nRight
fr.rc.nBottom = iHeightTwips& - BM * 1440
fr.rcPage.nBottom = fr.rc.nBottom
'- Fill rDocInfo structure
rDocInfo.cbSize = len(rDocInfo)
zString = "RTF Printer"
rDocInfo.lpszDocName = VARPTR(zString)
rDocInfo.lpszOutput = %NULL
'- Here we go
StartDoc pd.hDC, rDocInfo
StartPage pd.hDC
'- This does the printing. We send messages
' to the edit box telling it to format it's
' text to fit the Printer's DC.
'
iTextOut = 0
iTextAmt = SendMessage(rtfEdit, %WM_GETTEXTLENGTH, 0, 0)
do while iTextOut < iTextAmt
iTextOut = SendMessage(rtfEdit, %EM_FORMATRANGE, _
1, VARPTR(fr))
if iTextOut < iTextAmt then
EndPage pd.hDC
StartPage pd.hDC
fr.chrg.cpMin = iTextOut
fr.chrg.cpMax = -1
end if
loop
SendMessage rtfEdit, %EM_FORMATRANGE, 1, %NULL
'- Finish the printing.
EndPage pd.hDC
EndDoc pd.hDC
DeleteDC pd.hDC
SetCursor LoadCursor( %NULL, BYVAL %IDC_ARROW )
else
' MsgBox "Canceled !"
end if
END SUB
答案 1 :(得分:0)
Raymond Chen在他的博客上谈到了这个问题 How do I print the contents of a rich text control?
答案 2 :(得分:0)
我使用下面的扩展控件来实现我的RTF打印。
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();
}
}
}