delphitmemo

Calculating max chars per line in Delphi TMemo


I have a TMemo.

I´d like to put some text in each line of TMemo without the line wordwrap. I need calculate how many characters I can put in a line without TMemo make a wordwrap in that line.

pseudo code:

function calculate_max_chars_per_line_in_Memo():Integer;
var w,l:integer;
begin
   w:=getwidth from tmemo;
   l:=lenght of a font char;
   Result:=trunc(w/l);
end;

Is possible I do it?


Solution

  • Note that for most of fonts chars have variable width (Courier and Terminal are examples of fixed-width fonts). See TFont.Pitch.

    So if you are ready to use fixed fonts, find char width once with Canvas.TextWidth and use this value to determine max string length.

    For variable fonts you have to examine the width of every string - 'lllll' will shorter in pixels than 'wwwww' and so on. Of course, you could try to find the shortest char sequence with max width and use its length. Note that the widest char (and combination of chars with inter-symbol spaces) depends on the font used.

    var
      s: string;
      Margins: Integer;
    begin
      Margins := Memo1.Perform(EM_GETMARGINS, 0, 0);
      Margins := LongRec(Margins).Lo + LongRec(Margins).Hi;
      s := 'ababababababababababababababababababababababab';
    
      //be sure that Canvas font is the same as Memo font
      while Canvas.TextWidth(s) >= Memo1.ClientWidth - Margins - 1 do
        Delete(s, Length(s), 1);
      Memo1.Lines.Add(s);
    

    Alternative approach - find width of Memo to hold up the text with DrawText(Ex) WinAPI function.