我們知道在VS.NET環境下有一個RichTextBox控件可以很好的顯示Rtf文檔,可是有的時候我們需要以圖形的形式來顯示一個Rtf格式的文檔.但RichTextBox并不支援把顯示的内容存成圖檔,經過查找資料我得到了如下的代碼,使用這些代碼就可以把以RichTextBox顯示Rtf格式的内容很好的顯示為圖檔,或使用到Graphics中.
internal class PrintableRtf: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, RectangleF marginBounds, RectangleF pageBounds, Graphics g)
...{
//Calculate the area to render and print
RECT rectToPrint;
rectToPrint.Top = (int)(marginBounds.Top * anInch);
rectToPrint.Bottom = (int)(marginBounds.Bottom * anInch);
rectToPrint.Left = (int)(marginBounds.Left * anInch);
rectToPrint.Right = (int)(marginBounds.Right * anInch);
//Calculate the size of the page
RECT rectPage;
rectPage.Top = (int)(pageBounds.Top * anInch);
rectPage.Bottom = (int)(pageBounds.Bottom * anInch);
rectPage.Left = (int)(pageBounds.Left * anInch);
rectPage.Right = (int)(pageBounds.Right * anInch);
IntPtr hdc = g.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(this.Handle, EM_FORMATRANGE, wparam, lparam);
//Free the block of memory allocated
Marshal.FreeCoTaskMem(lparam);
//Release the device context handle obtained by a previous call
g.ReleaseHdc(hdc);
//Return last + 1 character printer
return res.ToInt32();
}
}
Rectangle rect = new Rectangle( 0 , 0 , 800 , 600 );
using (Bitmap bit = new Bitmap( 800 , 600 ))
... {
using (Graphics g = Graphics.FromImage(bit))
...{
int EndPoint = m_PrintableRtf.Print(0, this.m_PrintableRtf.TextLength, rect, rect, e.Graphics);
}
bit.Save(@"D: tf.bmp");
}