3

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?

Luiz Alves
  • 2,575
  • 4
  • 34
  • 75
  • 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 Feb 15 '16 at 13:59
  • Try something like here http://stackoverflow.com/questions/6804929/how-do-i-determine-the-height-of-a-line-of-text-in-a-tmemo-programmatically?rq=1 – Jan Doggen Feb 15 '16 at 15:14

1 Answers1

1

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.

MBo
  • 77,366
  • 5
  • 53
  • 86
  • Thank you. Will it possible you post a sample? – Luiz Alves Feb 15 '16 at 13:17
  • Have you checked help topic? This function is very simple to use. – MBo Feb 15 '16 at 13:24
  • I am not finding canvas in Tmemo – Luiz Alves Feb 15 '16 at 13:32
  • TMemo doesn't have a `Canvas`. You can use any other control with a canvas to do the job, however. – J... Feb 15 '16 at 13:43
  • I tried it, but no look: MCanvas:=TControlCanvas.Create; try MCanvas.Control:=Memo1; s:=st[0]; k:=MCanvas.textwidth(s); while k>Memo1.Width do begin s:=copy(s,1,length(s)-1); k:=MCanvas.textwidth(s); end; s:=copy(s,1,length(s)-1); finally MCanvas.Free; End; Memo1.Lines[0]:=s; – Luiz Alves Feb 15 '16 at 13:49
  • I added example. I had to subtract additional 1 to avoid wrapping in some cases. – MBo Feb 15 '16 at 16:57
  • 2
    Careful here, though - you're using the Form's `Canvas` to measure a string being output to the memo. If the form's font is different from the memo's font this won't work. If you're going to use the form's canvas this way you should save the canvas font to a temporary variable, copy the memo's font to the canvas, and then restore the canvas font afterwards. – J... Feb 15 '16 at 19:19
  • Thnak you Mbo, i will try it. – Luiz Alves Feb 16 '16 at 17:10