首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在DT_PATH_ELLIPSIS中使用Windows API DrawText

在DT_PATH_ELLIPSIS中使用Windows API DrawText
EN

Stack Overflow用户
提问于 2014-05-06 22:59:28
回答 2查看 1.8K关注 0票数 2

我正在尝试使用Windows API函数DrawText,但是没有得到我期望的结果。也许我在这里做错了什么,但当我阅读文档时,我真的看不出问题所在。我使用了下面的代码。

代码语言:javascript
复制
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“一个带有反斜杠()的字符串时,它似乎设置了省略号,但函数忽略了矩形测量值。

示例

代码语言:javascript
复制
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.    '
EN

回答 2

Stack Overflow用户

发布于 2014-05-11 12:14:23

下面是一个过程,如果字符串对于给定的rect来说太宽,它会绘制一个中间有省略号的字符串:

代码语言:javascript
复制
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):

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2021-04-30 18:08:16

基于@jthurman代码

优势:

*简化,

*更具普遍性

*修复错误

好好享受吧。

代码语言:javascript
复制
 { 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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23498234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档