Author: Tomas Rutkauskas
I have e.g. a RichEdit that I want to underlay with a grid for character placement.
TCanvas does not seem to be available for TRichedit So I draw the grid on the TForm
behind the richedit. How can I make the RichEdit transparent or how can I assign a
TCanvas to a TRichedit?
Answer:
Solve 1:
1
2 procedure OutputRTFtoBmp(RichHolder: TRichEdit; ImageHolder: TBitmap);
3 var
4 Range: TFormatRange;
5 TextBoundary: TRect;
6 begin
7 {Setup the Height and Width of our output}
8 ImageHolder.width := RichHolder.Width;
9 ImageHolder.height := RichHolder.Height;
10 if (bkGnd.Width <> 0) and (bkGnd.HEight <> 0) then
11 imageholder.canvas.Draw(0, 0, bkGnd)
12 else
13 with imageholder.canvas do
14 begin
15 brush.Color := richholder.color;
16 fillrect(cliprect);
17 end;
18 imageholder.canvas.Brush.Style := bsClear;
19 {Set the Size of the Rich Edit}
20 textboundary := rect(0, 0, RichHolder.Width * screen.Pixelsperinch,
21 RichHolder.Height * screen.Pixelsperinch);
22 {Set the Range record}
23 range.hdc := ImageHolder.Canvas.handle;
24 range.hdctarget := ImageHolder.Canvas.handle;
25 range.rc := textboundary;
26 range.rcpage := textboundary;
27 {Start at character zero}
28 range.chrg.cpMin := 0;
29 {Display all Characters}
30 range.chrg.cpMax := -1;
31 {Ask RTF to Draw}
32 Sendmessage(RichHolder.handle, EM_FORMATRANGE, 1, longint(@range));
33 {Cleanup RTF Cache}
34 sendmessage(RichHolder.handle, EM_FORMATRANGE, 0, 0);
35 end;
Solve 2:
This simply copies an RTF document to a canvas:
36 { ... }
37 var
38 Bitmap: TBitmap;
39 RichEdit: TRichEdit;
40
41 function PrintToCanvas(FromChar, ToChar: integer): Longint;
42 var
43 range: TFormatRange;
44 begin
45 FillChar(Range, SizeOf(TFormatRange), 0);
46 Range.hdc := Bitmap.Canvas.handle;
47 Range.hdcTarget := Bitmap.Canvas.Handle;
48 Range.rc.left := 0;
49 Range.rc.top := 0;
50 Range.rc.right := Bitmap.Width * 1440 div Screen.PixelsPerInch;
51 Range.rc.Bottom := Bitmap.Height * 1440 div Screen.PixelsPerInch;
52 Range.chrg.cpMax := ToChar;
53 Range.chrg.cpMin := FromChar;
54 Result := SendMessage(Richedit.Handle, EM_FORMATRANGE, 1, Longint(@Range));
55 SendMessage(RichEdit.handle, EM_FORMATRANGE, 0, 0);
56 end;
Solve 3:
Try following source code:
57
58 procedure DrawRTF(Bitmap: TBitmap; X1, Y1, X2, Y2: Integer; RichEdit: TRichEdit);
59 const
60 BitmapPixelsPerInch = 96;
61 BitmapTwipsPerPixel = 1440 div BitmapPixelsPerInch;
62 var
63 Range: TFormatRange;
64 begin
65 with Range do
66 begin
67 {convert the coordinates to twips (1/1440") }
68 hDC := Bitmap.Canvas.Handle; {DC handle}
69 hdcTarget := Bitmap.Canvas.Handle; {ditto}
70 rc := Rect(X1 * BitmapTwipsPerPixel, Y1 * BitmapTwipsPerPixel,
71 X2 * BitmapTwipsPerPixel, Y2 * BitmapTwipsPerPixel);
72 rcPage := rc;
73 chrg.cpMin := 0;
74 chrg.cpMax := -1; {RichEdit.GetTextLen;}
75 {Free cached information}
76 RichEdit.Perform(EM_FORMATRANGE, 0, 0);
77 {First measure the text, to find out how high the format rectangle will be.
78 The call sets fmtrange.rc.bottom to the actual height required, if all
79 characters in the selected
80 range will fit into a smaller rectangle.}
81 RichEdit.Perform(EM_FORMATRANGE, 0, DWord(@Range));
82 {Now render the text}
83 RichEdit.Perform(EM_FORMATRANGE, 1, DWord(@Range));
84 {Free cached information}
85 RichEdit.Perform(EM_FORMATRANGE, 0, 0);
86 end;
87 end;
Solve 4:
PaintTo draws the visible client area of a RichEdit control to the TCanvas. Use the
following method to render the complete content to your TCanvas. DestDCHandle is
TCanvas.Handle, R is the Rect in relation to your canvas, RichEdit is a TRichEdit
instance (can be invisible), PixelsPerInch is the Resolution (for screen e.g. 96).
88
89 procedure DrawRTF(DestDCHandle: HDC; const R: TRect;
90 RichEdit: TRichEdit; PixelsPerInch: Integer);
91 var
92 TwipsPerPixel: Integer;
93 Range: TFormatRange;
94 begin
95 TwipsPerPixel := 1440 div PixelsPerInch;
96 with Range do
97 begin
98 hDC := DestDCHandle; {DC handle}
99 hdcTarget := DestDCHandle; {ditto}
100 {Convert the coordinates to twips (1/1440")}
101 rc.Left := R.Left * TwipsPerPixel;
102 rc.Top := R.Top * TwipsPerPixel;
103 rc.Right := R.Right * TwipsPerPixel;
104 rc.Bottom := R.Bottom * TwipsPerPixel;
105 rcPage := rc;
106 chrg.cpMin := 0;
107 chrg.cpMax := -1; {RichEdit.GetTextLen;}
108 {Free cached information}
109 RichEdit.Perform(EM_FORMATRANGE, 0, 0);
110 {First measure the text, to find out how high the format rectangle will
111 be. The call sets fmtrange.rc.bottom to the actual height required, if all
112 characters in the selected range will fit into a smaller rectangle}
113 RichEdit.Perform(EM_FORMATRANGE, 0, DWord(@Range));
114 {Now render the text}
115 RichEdit.Perform(EM_FORMATRANGE, 1, DWord(@Range));
116 {Free cached information}
117 RichEdit.Perform(EM_FORMATRANGE, 0, 0);
118 end;
119 end;
Sample 1:
120
121 procedure TForm1.Button1Click(Sender: TObject);
122 var
123 RichEdit: TRichEdit;
124 bmp: TBitmap;
125 DestDCHandle: HDC;
126 begin
127 RichEdit := TRichEdit.Create(Self);
128 try
129 RichEdit.Visible := False;
130 RichEdit.Parent := Self;
131 {Win2k, WinXP}
132 RichEdit.Lines.LoadFromFile('filename.rtf');
133 bmp := TBitmap.Create;
134 try
135 bmp.width := 500;
136 bmp.height := 500;
137 DestDCHandle := bmp.Canvas.Handle;
138 DrawRTF(DestDCHandle, Rect(0, 0, bmp.Width, bmp.Height), RichEdit, 96);
139 Image1.Picture.Assign(bmp);
140 finally
141 bmp.Free;
142 end;
143 finally
144 RichEdit.Free;
145 end;
146 end;
Sample 2 (draw transparent):
147 procedure TForm1.Button1Click(Sender: TObject);
148 var
149 RichEdit: TRichEdit;
150 ExStyle: DWord;
151 bmp: TBitmap;
152 DestDCHandle: HDC;
153 begin
154 RichEdit := TRichEdit.Create(Self);
155 try
156 RichEdit.Visible := False;
157 RichEdit.Parent := Self;
158 {Win2k, WinXP}
159 ExStyle := GetWindowLong(RichEdit.Handle, GWL_EXSTYLE);
160 ExStyle := ExStyle or WS_EX_TRANSPARENT;
161 SetWindowLong(RichEdit.Handle, GWL_EXSTYLE, ExStyle);
162 RichEdit.Lines.LoadFromFile('filename.rtf');
163 bmp := TBitmap.Create;
164 try
165 bmp.LoadFromFile('filename.bmp');
166 DestDCHandle := bmp.Canvas.Handle;
167 {Win9x}
168 SetBkMode(DestDCHandle, TRANSPARENT);
169 DrawRTF(DestDCHandle, Rect(0, 0, bmp.Width, bmp.Height), RichEdit, 96);
170 Image1.Picture.Assign(bmp);
171 finally
172 bmp.Free;
173 end;
174 finally
175 RichEdit.Free;
176 end;
177 end;
|