Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2006 Apr : Measuring size full text of TRichEdit

www.cryer.info
Managed Newsgroup Archive

Measuring size full text of TRichEdit

Subject:Measuring size full text of TRichEdit
Posted by:no@spam.com
Date:1 Apr 2006 23:50:37 -0700

Hi,

I'd like to be able at run-time to measure the screen size of the text of a
TRichEdit so that I can resize the control
to show exactly the text.

For that, I created the following function, based on TRichEdit.Print:

{
--------------------------------------------------------------------------------
}
Function GetTextHeightOfRichEdit(Const RichEdit : TCustomRichEdit) : Integer;
Var
   Range: TFormatRange;
   LastChar, MaxLen, OldMap, LogX, LogY : Integer;
   SaveRect: TRect;
   DC : HDC;
Begin
     Result := 0;

     { We want to use the control itself as rendering DC: }
     DC := GetDC(RichEdit.Handle);
     LogX := GetDeviceCaps(DC, LOGPIXELSX);
     LogY := GetDeviceCaps(DC, LOGPIXELSY);

     FillChar(Range, SizeOf(TFormatRange), 0);
     with Range do
     begin
          hdc := DC;
          hdcTarget := DC;
          rc.left := 0;
          rc.top := 0;
          { The width of RichEdit will stay as it is, we want to know the
height of the text that fits in
            this width (converted to TWIPS): }
          rc.right := RichEdit.ClientWidth * 1440 div LogX;
          rc.bottom := 0;
          rcPage := rc;
          { Whole text: }
          chrg.cpMax := -1;
     End;

     SaveRect := Range.rc;
     LastChar := 0;
     MaxLen := RichEdit.GetTextLen;

     OldMap := SetMapMode(Range.hdc, MM_TEXT);
     SendMessage(RichEdit.Handle, EM_FORMATRANGE, 0, 0);
     try
          repeat
               Range.rc := SaveRect;
               Range.chrg.cpMin := LastChar;
               LastChar := SendMessage(RichEdit.Handle, EM_FORMATRANGE, 0,
LongInt(@Range));

               Inc(Result, (Range.rc.Bottom * LogY Div 1440));
          until (LastChar >= MaxLen) or (LastChar = -1);
     finally
          SendMessage(RichEdit.Handle, EM_FORMATRANGE, 0, 0);
          SetMapMode(Range.hdc, OldMap);
          ReleaseDC(RichEdit.Handle, DC);
     end;
End;


When I want to resize my RichEdit, I just have to do:
     RichEdit1.ClientHeight := GetTextHeightOfRichEdit(RichEdit1);

However, I have a small problem here:
It seems that the call to SendMessage(RichEdit.Handle, EM_FORMATRANGE, 0,
LongInt(@Range)) is executed for each line in my RichEdit, returning the
height of each line in Range.rc.Bottom instead of the whole text, hence the
need for me to add all the calculated heights in the function result via:
Inc(Result, (Range.rc.Bottom * LogY Div 1440)) inside the repeat loop.

In my Range param, I clearly specify that I want all the text measured
(chrg.cpMax := -1;) so what if wrong with my code?

Thanks for any help.
David.

Glossary

File Types

Replies:

www.cryer.info
Managed Newsgroup Archive