Delphi-在矩形中心绘制文本多行

Delphi-在矩形中心绘制文本多行,delphi,text,Delphi,Text,在Delphi中,我希望在树中绘制文本。我希望实现以下功能: 在树内垂直居中绘制文本 在树内水平居中绘制文本 如果有多行文字的空间(使用TRect的高度),请绘制多行文字 如果文本不适合树形图(在单行或多行上),则在文本后附加省略号 我可以看到Windows.DrawText()函数几乎涵盖了此功能,但是在编写文本时,多行和垂直居中是相互排斥的 我想知道这个功能是否内置在windows(2000+)中?如果没有,是否有一种方法可以在不编写自己的函数的情况下执行此操作?首先使用DT\u CALCR

在Delphi中,我希望在树中绘制文本。我希望实现以下功能:

  • 在树内垂直居中绘制文本
  • 在树内水平居中绘制文本
  • 如果有多行文字的空间(使用TRect的高度),请绘制多行文字
  • 如果文本不适合树形图(在单行或多行上),则在文本后附加省略号
  • 我可以看到Windows.DrawText()函数几乎涵盖了此功能,但是在编写文本时,多行和垂直居中是相互排斥的


    我想知道这个功能是否内置在windows(2000+)中?如果没有,是否有一种方法可以在不编写自己的函数的情况下执行此操作?

    首先使用
    DT\u CALCRECT
    测量文本。传递
    DT_WORDBREAK
    以指定已启用换行。这将允许您找到文本所需的高度。然后,您可以在代码中计算垂直偏移量,该偏移量为垂直居中的文本,并绘制到该偏移量。

    对不起,这是以前所有答案和注释的组合。但OP似乎需要更多的帮助

    function DrawTextCentered(Canvas: TCanvas; const R: TRect; S: String): Integer;
    var
      DrawRect: TRect;
      DrawFlags: Cardinal;
      DrawParams: TDrawTextParams;
    begin
      DrawRect := R;
      DrawFlags := DT_END_ELLIPSIS or DT_NOPREFIX or DT_WORDBREAK or
        DT_EDITCONTROL or DT_CENTER;
      DrawText(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags or DT_CALCRECT);
      DrawRect.Right := R.Right;
      if DrawRect.Bottom < R.Bottom then
        OffsetRect(DrawRect, 0, (R.Bottom - DrawRect.Bottom) div 2)
      else
        DrawRect.Bottom := R.Bottom;
      ZeroMemory(@DrawParams, SizeOf(DrawParams));
      DrawParams.cbSize := SizeOf(DrawParams);
      DrawTextEx(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags, @DrawParams);
      Result := DrawParams.uiLengthDrawn;
    end;
    
    procedure TForm1.FormPaint(Sender: TObject);
    const
      S = 'This is a very long text as test case for my paint routine.';
    var
      R: TRect;
    begin
      SetRect(R, 100, 100, 200, 140);
      Canvas.Rectangle(R);
      InflateRect(R, -1, -1);
      Caption := Format('%d characters drawn', [DrawTextCentered(Canvas, R, S)]);
    end;
    
    函数drawTextCentred(Canvas:TCanvas;const R:TRect;S:String):整数;
    变量
    DrawRect:TRect;
    红衣主教;
    DrawParams:TDrawTextParams;
    开始
    DrawRect:=R;
    DrawFlags:=DT_END_省略号或DT_NOPREFIX或DT_字中断或
    DT_编辑控制或DT_中心;
    DrawText(Canvas.Handle、PChar、-1、DrawRect、DrawFlags或DT_CALCRECT);
    DrawRect.Right:=R.Right;
    如果DrawRect.Bottom
    您不能使用TLabel吗?我认为它具备所需的所有功能。是的,它可能具备,但我不想使用标签,我有一个画布可供绘制。我尝试了此方法,但由于某种原因,当指定DT_WORDBREAK时,DT_WORD_省略号被忽略。此例程当前不在rect之外绘制文本(并且不显示“…”),是否有方法可以准确获取绘制的文本(或长度)?@Simon DrawTextParams.UILengthDrawed返回绘制的字符数,包括因DT_WORD_省略号而产生的3点。@Simon-我认为您正在寻找
    DT_CENTER或DT_WORDBREAK或DT_END_省略号或DT_MODIFYSTRING
    这将包装文本,水平居中,并在文本末尾显示省略号,以防最后一行无法完全显示。您不需要DT_MODIFYSTRING,这仅用于绘画后的文本处理。使用DT_EDITCONTROL仅显示全部可见线。没有,有部分线条画出来,这可能是没有看到省略号的原因。我看不出deamon_x和这个版本之间的区别,但是这个很有效!!!!谢谢:)这行是关键:DT_END_省略号或DT_NOPREFIX或DT_WORDBREAK或DT_EDITCONTROL或DT_CENTER;我知道结果很简单,但任何其他标志组合都不起作用!如果可以的话,我会分割这些点:)@NGLN我希望你的例子能解决我的问题,但事实并非如此,我尝试在指定的矩形内对文本进行v形居中处理,但是如果文本不合适并且绘制了省略号,则DrawRect.Bottom会报告一个代表3行的值,即使只有2行清晰地绘制出来。这是一个显示问题的示例图像(文本后面较暗的区域是指定的矩形)。@blant我认为最好针对您的具体问题提出一个新问题。