Q:  How can I tell how many lines are showing in a memo?

A:  Here is the short and elegant way that works:

function TForm1.MemoLinesShowing(memo: TMemo): integer;
var
  R: TRect;
begin
  memo.Perform(EM_GETRECT, 0, Longint(@R));
  result := (R.Bottom - R.Top) div Canvas.TextHeight('XXX');
end;

The caveat with this code is that it must use the same font for the memo as the form uses.  If the fonts are different, then  there is a problem or two to be solved.  You can't just get the  font height.  (That would be too easy. <G>)  Delphi caches the font but doesn't acutally select the font into the DC (canvas) until it is actually going to draw something.  That is why we  have do jump through these hoops.  The problem in getting the
text height for a memo component is the font used in the memo  is not selected into the dc until a draw event happens. The cure is to get the font and select it into the dc, then calc the text height!

function TForm1.MemoLinesShowingLong(memo: TMemo): integer;
Var
  oldfont: HFont;  {the old font}
  dc: THandle;     {a dc handle}
  i: integer;      {loop variable}
  tm: TTextMetric; {text metric structure}
  TheRect: TRect;
begin
  dc := GetDC(Memo.handle); {Get the Dc for the memo}
  oldFont := SelectObject(dc, Memo.Font.handle); {Select the memo's font}

  GetTextMetrics(dc, tm); {Get the text metric info}
  memo.perform(em_GetRect, 0, longint(@TheRect));
  result := (TheRect.bottom - TheRect.top) DIV (tm.tmHeight + tm.tmExternalLeading);

  SelectObject(dc, oldfont); {Select the old font}
  ReleaseDC(Memo.handle, dc); {Release the Dc}
end;