delphirichedit

How to get text extent of RichEdit in Delphi


Does anyone know how to get the width and height of text in a TRichEdit control, in the same way that you would use TextWidth and TextHeight on a TCanvas?

The reason I need to know this doing this is I have a RichEdit on a non-visible form that I copy the contents of to a canvas using Richedit.Perform(EM_FORMATRANGE, ...). The problem is that the EM_FORMATRANGE requires a parameter of type TFormatRange in which the target rect is specified, but I don't know what the rect should be because I don't know in advance the size of the contents in the RichEdit. Hope that makes sense.


Solution

  • Again use EM_FORMATRANGE for measuring, see EM_FORMATRANGE Message on MSDN:

    wParam Specifies whether to render the text. If this parameter is a nonzero value, the text is rendered. Otherwise, the text is just measured.

    Generally you would already have a destination area, which has a width and height, where you'd do the drawing, like printing on a paper or producing a preview on a predefined surface. A most simple example for a predefined width to get the required height could be;

    var
      Range: TFormatRange;
      Rect: TRect;
      LogX, LogY, SaveMapMode: Integer;
    begin
      Range.hdc := ACanvas.Handle;
      Range.hdcTarget := ACanvas.Handle;
    
      LogX := GetDeviceCaps(Range.hdc, LOGPIXELSX);
      LogY := GetDeviceCaps(Range.hdc, LOGPIXELSY);
    
      Range.rc.Left := 0;
      Range.rc.Right := RichEdit1.ClientWidth * 1440 div LogX; // Any predefined width
      Range.rc.Top := 0;
      Range.rc.Bottom := Screen.Height * 1440 div LogY; // Some big number
      Range.rcPage := Range.rc;
      Range.chrg.cpMin := 0;
      Range.chrg.cpMax := -1;
      RichEdit1.Perform(EM_FORMATRANGE, 0, Longint(@Range));
    
      ShowMessage(IntToStr(Range.rc.Bottom * LogY div 1440)); // Get the height
      RichEdit1.Perform(EM_FORMATRANGE, 0, 0); // free cache
    


    For a more complete example see this article, or in general any RichEdit previewing/printing code...