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