Delphi: Как нарисовать некоторый текст с требуемой шириной и количеством строк, с завершающим многоточием - PullRequest
4 голосов
/ 04 апреля 2011

Мне нужно нарисовать некоторый текст в ячейке таблицы с фиксированной шириной (в пикселях) и фиксированным количеством строк текста. Если текст обрезается по прямоугольнику ячейки, он должен заканчиваться многоточием. Проблема в том, что я не могу правильно рассчитать текстовый прямоугольник (или процедура TextRect / DrawText работает неправильно, я не уверен).

Я пытался использовать этот метод вычисления текстового прямоугольника:

var
  TextRect: TRect;
  tm: TEXTMETRIC;
...
GetTextMetrics(Canvas.Handle, tm);
TextLineHeight := tm.tmHeight + tm.tmExternalLeading;

TextRect.Bottom := TextRect.Top + TextLineHeight * NumberOfLines;
Canvas.TextRect(TextRect, 'some long long long text',
  [tfTop, tfLeft, tfEndEllipsis, tfWordBreak]);

Прямоугольник отсечения рассчитан правильно, но многоточие не отображается.

Многоточие появляется, когда я уменьшаю высоту прямоугольника отсечения на 1 пиксель:

TextRect.Bottom := TextRect.Top + TextLineHeight * NumberOfLines - 1;

Но некоторые пиксели нижней строки моего текста обрезаются.

Как это сделать правильно?

Ответы [ 2 ]

4 голосов
/ 04 апреля 2011

Поскольку API ставит конечный многоточие только тогда, когда последняя строка не помещается в указанном прямоугольнике, одним из обходных путей может быть указание tfModifyString в параметрах форматирования при первом вызове TextRect с прямоугольником уменьшенной высоты , затем снова вызовите TextRect с прямоугольником правильного размера и измененным текстом:

var
  Text: string;
...

  Text := 'some long long long text';
  SetLength(Text, Length(Text) + 4); // as per DrawTextEx documentation

  Dec(TextRect.Bottom);
  Canvas.TextRect(TextRect, Text,
      [tfTop, tfLeft, tfEndEllipsis, tfWordBreak, tfModifyString]);

  Inc(TextRect.Bottom);
  Canvas.TextRect(TextRect, Text, [tfTop, tfLeft, tfWordBreak]);


Я бы следил за тем, чтобы будущая версия ОС решила полностью обрезать последнюю строку, если она не совсем умещается в прямоугольнике ..:)

0 голосов
/ 04 апреля 2011

Я бы попробовал вычислить нужный прямоугольник через Canvas.TextRect(..., [tfCalcRect, ...]).

...