Delphi: How to draw some text in requested width and number of lines, with ending ellipsis?
I need to draw some text in a table cell with 开发者_开发知识库fixed width (in pixels) and fixed number of text lines. If the text is clipped by cell rectangle, it must end with ellipsis. The problem is I can't calculate the text rectangle correctly (or the TextRect/DrawText procedure isn't working correctly, I'm not sure).
I tried to use this method of calculating text rectangle:
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]);
The clipping rectangle has been calculated correctly, but the ellipsis isn't appearing.
Ellipsis appearing when I decrease the height of clipping rectangle by 1 pixel:
TextRect.Bottom := TextRect.Top + TextLineHeight * NumberOfLines - 1;
But some pixels of the bottom line of my text are clipped then.
How to do it correctly?
Since the api puts the end-ellipsis only when the last line does not fit in the specified rectangle, one workaround could be to specify tfModifyString
in formatting options in a first call to 'TextRect' with a rectangle with reduced height, then call 'TextRect' again with a proper sized rectangle and the modified text:
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]);
I'd be keeping an eye though, in case a future version of the OS decides to clip the last line entirely if it doesn't entirely fit in the rectangle.. :)
I'd try calculating the needed rectangle via Canvas.TextRect(..., [tfCalcRect, ...])
.
精彩评论