procedure TfrmMain.btnSetHeightClick(Sender: TObject); var i, Max: Integer; begin Max := 0; Canvas.Font.Assign(redt.Font); for i := 0 to Length(redt.Text) do if Max < Canvas.TextHeight(redt.Text[i + 1])then Max := Canvas.TextHeight(redt.Text[i + 1]); redt.Height := 4 * Max; end; 

With this code, I set the height for, say, four lines. It turns out the following:

example01 http://savepic.ru/10588114.jpg

Some letters on the last line are cut off (Letters: " y ", " p ", " d "). You can, of course, add a few pixels and it will be normal, but if you increase / decrease the font, then everything will be lost. So if you have to pick up your figure for each size, that is good. Also, there is a problem that the character elements from the next line beyond the last visible line are visible.

How can you measure the actual height of the line so that each line fits completely and the elements of characters from the line that follows the last visible line are not visible (in the figure this is the fourth line)?

  • Search in richedit line spacing, the interval in front of the paragraph and add them to the "technical" height of 4 lines? - kami
  • one
    I think, here to the height you need to add the size of the border. You can calculate it using AdjustWindowRect . - mega
  • All values ​​are equal to zero, if you look through EM_GETPARAFORMAT, without prior setting values ​​to parameters via EM_SETPARAFORMAT. - user214690

2 answers 2

UPD: The indentation sizes I had correctly calculated for the 14th size Times New Roman font. The total height is 6 pixels, you can safely substitute for calculations on any font size. On other font sizes, incorrect calculation of the height of indents is noticed.

Thanks to Comrade Mega for the tip. I enclose a code listing:

 function TfrmMain.GetLastVisibleLine(RichEdit: TRichEdit): Integer; const EM_EXLINEFROMCHAR = WM_USER + 54; var r: TRect; i: Integer; begin { The EM_GETRECT message retrieves the formatting rectangle of an edit control. } RichEdit.Perform(EM_GETRECT, 0, Longint(@r)); r.Left := r.Left + 1; r.Top := r.Bottom - 2; { The EM_CHARFROMPOS message retrieves information about the character closest to a specified point in the client area of an edit control } i := RichEdit.Perform(EM_CHARFROMPOS, 0, Integer(@r.topleft)); { The EM_EXLINEFROMCHAR message determines which line contains the specified character in a rich edit control } Result := RichEdit.Perform(EM_EXLINEFROMCHAR, 0, i); end; procedure TfrmMain.FormShow(Sender: TObject); var r: TRect; begin redt.Lines.LoadFromFile('text.txt'); r.TopLeft.X := 0; r.TopLeft.Y := 0; r.BottomRight.X := redt.ClientWidth; r.BottomRight.Y := redt.ClientHeight; AdjustWindowRect(r, WS_BORDER, False); BordersHeight := r.BottomRight.Y - (GetLastVisibleLine(redt) * GetCharHeight); end; procedure TfrmMain.btnSetHeightClick(Sender: TObject); var CharHeight: Integer; begin Canvas.Font.Assign(redt.Font); CharHeight := GetCharHeight; redt.Height := (4 * CharHeight) + BorderHeight; end; procedure TfrmMain.btnSetFontClick(Sender: TObject); begin if dlgFont.Execute then redt.Font.Assign(dlgFont.Font); end; function TfrmMain.GetCharHeight: Integer; var i, Max: Integer; begin Max := 0; Canvas.Font.Assign(redt.Font); for i := 0 to Length(redt.Text) do if Max < Canvas.TextHeight(redt.Text[i + 1])then Max := Canvas.TextHeight(redt.Text[i + 1]); Result := Max; end; 

Go through the code:

The GetLastVisibleLine function determines the number of the last visible line.

At the OnShow event of the form, we know the total height of the upper and lower indents in pixels (we do not store it in a local variable and generally do not change the value while the form is being displayed).

The btnSetHeightClick procedure hangs on the button and sets a new height for RichEdit , taking into account the total height of the upper and lower indents and the number of lines (I have four lines).

The GetCharHeight function determines the current height of a character in RichEdit .

This example correctly exposes (at least I think so, I have not tested much) the height of RichEdit for the specified number of rows. When changing the font, the height recalculation is also correct. No truncation of the characters of the string and the display of the symbols of the string following the last visible line were found.

     CharHeight := Canvas.TextHeight(redt.Text[1]); 

    does not always return what is needed (for example, if Text[1] is a space, or there is no text at all), then

     CharHeight := Canvas.TextHeight('Wj'); 

    Just keep in mind that in RichEdit there may be different fonts even on the same line, in this case nothing will work.


    If you just need to make the height of the whole richedit by the size of the text, then I did this, for example:

     procedure THelpPopup.reHelpResizeRequest(Sender: TObject; Rect: TRect); begin BoundsRect := Rect; // выставляем размер формы равной размеру RichEdit end; 

    And, accordingly, initially the size of richedita did the minimum (just before changing the content).

    PS: The code is the handler of the OnResizeRequest TRichEdit .

    • I will consider, the code corrected. In general, I do not foresee the use of several fonts in one RichEdit. - user214690
    • I expanded the answer, compared to the comment, added how to resize the form compared to the text in TRichEdit . - Alekcvp pm
    • Had seen. Useful "crutch" :) - user214690