我正在尝试使用Windows API函数DrawText但是没有得到我期望的结果。也许我在这里做错了,但是当我阅读文档时,我真的没有看到问题。我正在使用以下代码。
function GetEllipsisString(Font: TFont; const Text: string;
Width: integer): String;
var
DC: HDC;
SaveFont: HFont;
R: TRect;
begin
DC := GetDC(0);
try
SaveFont := SelectObject(DC, Font.Handle);
R := Rect (0, 0, Width-1, 0);
Result := Text+' ';
Winapi.Windows.DrawtextW (DC, PChar(Result), Length(Result), R,
DT_CALCRECT+DT_LEFT+DT_PATH_ELLIPSIS+DT_MODIFYSTRING);
SelectObject(DC, SaveFont);
finally
ReleaseDC(0, DC);
end;
end;
DT_PATH_ELLIPSIS似乎什么也没做。我用DT_END_ELLIPSIS尝试了它,这给了我一些结果(见例子)。当我给参数“Text”一个带有反斜杠(\)的字符串时,它似乎设置省略号,但函数忽略了rect测量。
Text = 'This text has to many characters to fit.'
DT_END_ELLIPSIS returns 'This text has to m...'#0'characters to fit. '
DT_PATH_ELLIPSIS returns 'This text has to many characters to fit. '
答案 0 :(得分:0)
这是一个过程,如果字符串对于给定的rect来说太宽,则在中间绘制一个带省略号的字符串:
procedure DrawTextWithMiddleEllipsis(Canvas: TCanvas; Text: string; DrawRect:
TRect; Flags: Integer);
var
S, LastS: string;
R: TRect;
Sz: TSize;
RectWidth, I: Integer;
begin
S := Text;
R := DrawRect;
GetTextExtentPoint32(Canvas.Handle, S, Length(S), Sz);
RectWidth := DrawRect.Right - DrawRect.Left;
if Sz.cx > RectWidth then
begin
//The string is too wide. Need to cut it down with ellipsis
//Start with the smallest possible truncated-and-ellipsis-modified string,
//and expand until we have the biggest one that can fit
S := '...';
for I := 1 to Length(Text) div 2 do
begin
LastS := S;
//Get the first I chars, then the ellipsis, then the last I chars
S := Copy(Text, 1, I) + '...' + Copy(Text, Length(Text) - I + 1, I);
GetTextExtentPoint32(Canvas.Handle, S, Length(S), Sz);
if Sz.cx > RectWidth then
begin
DrawText(Canvas.Handle, LastS, Length(LastS), DrawRect, Flags);
Break;
end;
end;
end else
//The string will fit in the width of the given rect, don't mess with it
DrawText(Canvas.Handle, S, Length(S), DrawRect, Flags);
end;
以下是其被调用(PaintBox1
为TPaintBox
)的示例:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
S: string;
R: TRect;
begin
S := 'This is extra long text that should overflow';
R := PaintBox1.ClientRect;
DrawTextWithMiddleEllipsis(PaintBox1.Canvas, S, R, DT_LEFT or DT_TOP);
end;
答案 1 :(得分:0)
基于@jthurman 代码
优点:
*简化,
*更通用
*修复了一个错误
享受。
{ Takes a long string and truncates it in the middle. Example: '123...789' }
function GetEllipsisText(CONST s: string; Canvas: TCanvas; MaxWidth: Integer; Flags: Integer= DT_LEFT or DT_TOP): string;
var
NewStr, LastStr: string;
TextSize: TSize;
EllipsisSize: Integer;
begin
NewStr := '...';
EllipsisSize:= Canvas.TextWidth(NewStr);
GetTextExtentPoint32(Canvas.Handle, s, Length(s), TextSize);
if TextSize.cX > MaxWidth
then
//Start with the smallest possible truncated-and-ellipsis-modified string, and expand until we have the biggest one that can fit
for VAR i:= 1 to Length(s) div 2 do
begin
LastStr := NewStr;
NewStr := Copy(s, 1, I) + '...' + Copy(s, Length(s) - I + 1, I); // Get the first I chars, then the ellipsis, then the last I chars
GetTextExtentPoint32(Canvas.Handle, NewStr, Length(NewStr), TextSize);
if TextSize.cx > (MaxWidth - EllipsisSize)
then Exit(LastStr);
end
else
Result:= s; //The string will fit in the width of the given rect, don't mess with it
end;