2
votes

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?

1
You could set the wordwarp property of the Memo to False. No word wrapping anymore and you can enable a horizontal scrollbar when needed by setting the Scrollbars property. You only need to fiddle with Character width if you need to adjust the input based upon the Memo output width,.Ritsaert Hornstra

1 Answers

1
votes

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.