C# Code:
1: using System;
2: using System.Drawing;
3: using System.Drawing.Imaging;
4: using System.Runtime.InteropServices;
5: using System.Windows.Forms;
6: 7: public static class GraphicDrawRtfText
8: {9: private static RichTextBoxDrawer rtfDrawer;
10: 11: 12: public static void DrawRtfText(Graphics graphics, string rtf, Rectangle layoutArea, Rectangle targetArea)
13: {14: if (rtfDrawer == null)
15: {16: rtfDrawer = new RichTextBoxDrawer();
17: } 18: rtfDrawer.Rtf = rtf; 19: rtfDrawer.Draw(graphics, layoutArea, targetArea); 20: } 21: 22: 23: private class RichTextBoxDrawer : RichTextBox
24: {25: //Code converted from code found here: http://support.microsoft.com/kb/812425/en-us
26: 27: //Convert the unit used by the .NET framework (1/100 inch)
28: //and the unit used by Win32 API calls (twips 1/1440 inch)
29: private const double anInch = 14.4;
30: 31: protected override CreateParams CreateParams
32: { 33: get 34: {35: CreateParams createParams = base.CreateParams;
36: if (SafeNativeMethods.LoadLibrary("msftedit.dll") != IntPtr.Zero)
37: {38: createParams.ExStyle |= SafeNativeMethods.WS_EX_TRANSPARENT; // transparent
39: createParams.ClassName = "RICHEDIT50W";
40: }41: return createParams;
42: } 43: } 44: 45: 46: public void Draw(Graphics graphics, RectangleF layoutArea, RectangleF targetArea)
47: {48: //Calculate the area to render.
49: SafeNativeMethods.RECT rectLayoutArea;50: rectLayoutArea.Top = (int) (0*anInch);
51: rectLayoutArea.Bottom = (int) (targetArea.Bottom*anInch);
52: rectLayoutArea.Left = (int) (0*anInch);
53: rectLayoutArea.Right = (int) (targetArea.Right*anInch);
54: 55: 56: Bitmap Bmp = new Bitmap((int) layoutArea.Width,
57: (int) layoutArea.Height, PixelFormat.Format32bppArgb);
58: 59: 60: Graphics g = Graphics.FromImage(Bmp); 61: IntPtr hdc = g.GetHdc(); 62: 63: //create a metafile, convert the size to himetrics
64: //Metafile metafile = new Metafile(hdc, new
65: //RectangleF(0, 0, layoutArea.Width * 26, layoutArea.Height * 26));
66: 67: Metafile metafile = new Metafile(hdc, new
68: RectangleF(0, 0, layoutArea.Width, layoutArea.Height), 69: MetafileFrameUnit.Pixel); 70: g.ReleaseHdc(hdc); 71: g.Dispose(); 72: 73: g = Graphics.FromImage(metafile); 74: IntPtr hDCEMF = g.GetHdc(); 75: 76: SafeNativeMethods.FORMATRANGE fmtRange;77: fmtRange.chrg.cpMax = -1; //Indicate character from to character to
78: fmtRange.chrg.cpMin = 0;79: fmtRange.hdc = hDCEMF; //Use the same DC for measuring and rendering
80: fmtRange.hdcTarget = hDCEMF; //Point at printer hDC
81: fmtRange.rc = rectLayoutArea; //Indicate the area on page to print
82: fmtRange.rcPage = rectLayoutArea; //Indicate size of page
83: 84: IntPtr wParam = IntPtr.Zero;85: wParam = new IntPtr(1);
86: 87: //Get the pointer to the FORMATRANGE structure in memory
88: IntPtr lParam = IntPtr.Zero; 89: lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));90: Marshal.StructureToPtr(fmtRange, lParam, false);
91: 92: SafeNativeMethods.SendMessage(Handle, 93: SafeNativeMethods.EM_FORMATRANGE, wParam, lParam); 94: 95: //Free the block of memory allocated
96: Marshal.FreeCoTaskMem(lParam); 97: 98: //Release the device context handle obtained by a previous call
99: g.ReleaseHdc(hDCEMF); 100: g.Dispose(); 101: 102: 103: graphics.DrawImage(metafile, layoutArea.Location); 104: } 105: 106: #region SafeNativeMethods
107: 108: private static class SafeNativeMethods
109: {110: [DllImport("USER32.dll")]
111: public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
112: 113: [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
114: public static extern IntPtr LoadLibrary(string lpFileName);
115: 116: [StructLayout(LayoutKind.Sequential)]117: public struct RECT
118: {119: public int Left;
120: public int Top;
121: public int Right;
122: public int Bottom;
123: } 124: 125: [StructLayout(LayoutKind.Sequential)]126: public struct CHARRANGE
127: {128: public int cpMin; //First character of range (0 for start of doc)
129: public int cpMax; //Last character of range (-1 for end of doc)
130: } 131: 132: [StructLayout(LayoutKind.Sequential)]133: public struct FORMATRANGE
134: {135: public IntPtr hdc; //Actual DC to draw on
136: public IntPtr hdcTarget; //Target DC for determining text formatting
137: public RECT rc; //Region of the DC to draw to (in twips)
138: public RECT rcPage; //Region of the whole DC (page size) (in twips)
139: public CHARRANGE chrg; //Range of text to draw (see earlier declaration)
140: } 141: 142: public const int WM_USER = 0x0400;
143: public const int EM_FORMATRANGE = WM_USER + 57;
144: public const int WS_EX_TRANSPARENT = 0x20;
145: 146: } 147: 148: #endregion
149: } 150: }
RichTextBox's zoom factor =1
RichTextBox's zoom factor =2
note:
Uses a RichTextBox control and sends it an EM_FORMATRANGE that can draw some rft to the screen(image) .
But this method can't zoom the image(RichTextBox's zoom factor no effect).
So you can draw to a metafile and set the ScaleTrasform of the Graphics object and draw the metafile.
Of course,the output image is not perfect(not the same as RichTextBox's output).
Refences:
1.http://support.microsoft.com/kb/812425/zh-cn

