Note this was pulled mostly from the Delphi forums, probably Peter Below's source originally. Feel free to use/include as you see fit.
- Code: Select all
function TPrintPreview.getRichTextRect(var Rect: TRect; RichEdit: TCustomRichEdit; pOffset: PInteger=nil): Integer;
var
Range: TFormatRange;
OldMap: Integer;
SaveRect: TRect;
SaveIndex: Integer;
begin
Result := -1;
FillChar(Range, SizeOf(TFormatRange), 0);
Range.hdc := Canvas.Handle;
Range.hdcTarget := Range.hdc;
Range.rc.Left := ConvertUnit(Rect.Left, Units, mmTWIPS);
Range.rc.Top := ConvertUnit(Rect.Top, Units, mmTWIPS);
Range.rc.Right := ConvertUnit(Rect.Right, Units, mmTWIPS);
Range.rc.Bottom := ConvertUnit(Height, Units, mmTWIPS);
Range.rcPage := Range.rc;
Range.chrg.cpMax := -1;
if pOffset = nil then
Range.chrg.cpMin := 0
else
Range.chrg.cpMin := pOffset^;
SaveRect := Range.rc;
SaveIndex := SaveDC(Range.hdc);
OldMap := SetMapMode(Range.hdc, MM_TEXT);
RichEdit.Perform(EM_FORMATRANGE, 0, 0);
try
// Measure the text to find out how high the format rectangle
// will be. The call sets fmtrange.rc.bottom to the actual height
// required, if all characters in the selected range will fit into
// a smaller rectangle,
Range.chrg.cpMin := RichEdit.Perform( EM_FORMATRANGE, 0, Integer(@Range));
if Range.chrg.cpMin >= RichEdit.GetTextLen then
begin
Rect.Bottom := ConvertUnit(Range.rc.Bottom, mmTWIPS, Units);
Result := Rect.Bottom;
end;
finally
RichEdit.Perform(EM_FORMATRANGE, 0, 0);
RestoreDC(Range.hdc, SaveIndex);
SetMapMode(Range.hdc, OldMap);
end;
end;