Printing 如何在任何设备contenxt上以正确的格式打印富文本框内容?
我希望将格式为的富文本框内容打印到任何设备上下文,例如,我希望在面板或与实际打印设备关联的任何其他控件上打印 我使用面板模拟打印预览,从自定义设计的表单中绘制一些内容,富文本内容是该表单的内容之一Printing 如何在任何设备contenxt上以正确的格式打印富文本框内容?,printing,rtf,Printing,Rtf,我希望将格式为的富文本框内容打印到任何设备上下文,例如,我希望在面板或与实际打印设备关联的任何其他控件上打印 我使用面板模拟打印预览,从自定义设计的表单中绘制一些内容,富文本内容是该表单的内容之一 有没有解决这个问题的最佳方案???下面是将rtf控件的内容打印到打印机的代码。我可以适应打印到任何旧dc相当容易。该语言是powerbasic,但可以很容易地翻译成C、pascal或其他语言: SUB PrintRichTextBox ( hWnd as LONG, hInst as LONG, r
有没有解决这个问题的最佳方案???下面是将rtf控件的内容打印到打印机的代码。我可以适应打印到任何旧dc相当容易。该语言是powerbasic,但可以很容易地翻译成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
子PrintRichTextBox(hWnd为长,hInst为长,rtfEdit为长,LM为单_
RM为单个,TM为单个,BM为单个)
'
“目的:
'打印给定句柄的RTF文本框的内容
'调用程序的句柄和页边距。
'
“参数:
'hWnd=父窗口(用于打印公共dlg)
'hInst=调用程序的实例
'rtfEdit=富编辑控件的句柄
'LM=以英寸为单位的左边距
'RM=右边距(英寸)
'TM=以英寸为单位的上边距
'BM=以英寸为单位的底部边距
'
变暗fr作为格式化范围
将rDocInfo设置为文档信息
把它调暗就行了
暗淡的,如长
将pd设置为打印DLGAPI
尺寸Z字符串为ASCIIZ*200
朦胧的iWidthTwips&
调暗iHeightTwips&
“-设置“打印公用”对话框
pd.lStructSize=长度(pd)
pd.hwndOwner=hWnd
pd.hDevMode=%NULL
pd.hDevNames=%NULL
pd.nFromPage=0
pd.nToPage=0
pd.nMinPage=0
pd.nmappage=0
pd.nCopies=0
pd.hInstance=hInst
pd.Flags=%pd\u RETURNDC或%pd\u NOPAGENUMS或%pd\u PRINTSETUP
pd.lpfnSetupHook=%NULL
pd.lpPrintSetupTemplateName=%NULL
pd.lpfnPrintHook=%NULL
pd.lpPrintTemplateName=%NULL
如果打印DLG(pd),则
SetCursor LoadCursor(%NULL,BYVAL%IDC\u WAIT)
“-填充格式范围结构
'
“注:
“这让我感到很不舒服。我在看那本书
微软出版社称之为Windows 95编程
“Iterface。它(通过例子)说
'Rectagle是以像素为单位定义的。这不管用。
然而,SDK表示,需要对测量结果进行分析
“抽搐!这似乎很有效。
'
'
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
'-获取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结构
rDocInfo.cbSize=len(rDocInfo)
zString=“RTF打印机”
rDocInfo.lpszDocName=VARPTR(zString)
rDocInfo.lpszOutput=%NULL
-我们开始
StartDoc pd.hDC,rDocInfo
起始页pd.hDC
“-这不需要打印。我们发送消息
'到编辑框,告诉它格式化
'文本以适合打印机的DC。
'
iTextOut=0
iTextAmt=SendMessage(rtfEdit,%WM\u GETTEXTLENGTH,0,0)
在iTextOut
我使用了下面的扩展控件来实现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();
}
}
}
谢谢你提供资料,但我是个C语言的人,翻译成C语言有点困难。。有什么帮助吗?我不会用c语言编程,所以我帮不了多少忙。然而,上面的代码很容易翻译成C。重要的调用主要是win32 api调用。常量(#define)以%开头。出于某种原因,我在一些变量上加了一个类型后缀(我十多年前写过这段代码)。e、 iWidthTwips&只是意味着iWidthTwips是一个长(32位)整数。asciiz*200是char[200]。我已经使用了下面的代码来实现我的要求,如果有人寻找此类问题,它将有所帮助。