【问题标题】:Delphi - Draw text multiline in the centre of a rectDelphi - 在矩形中心绘制多行文本
【发布时间】:2011-10-23 20:25:36
【问题描述】:

在 Delphi 中,我希望在 TRect 中绘制文本。我希望有以下功能:

  1. 在 TRect 中垂直居中绘制文本
  2. 在 TRect 中水平居中绘制文本
  3. 如果有超过 1 行文本的空间(使用 TRect 的高度),则绘制多行文本
  4. 如果文本不适合 TRect(单行或多行),则将省略号附加到文本中。

我可以看到 Windows.DrawText() 函数几乎涵盖了这个功能,但是在编写文本时,多行和垂直居中是相互排斥的。

我想知道这个功能是否内置在 Windows (2000+) 中?如果没有,有没有办法在不编写我自己的函数的情况下做到这一点?

【问题讨论】:

  • 你不能使用 TLabel 吗?我认为它具有所需的所有功能。
  • 是的,它可能会,但我不想使用标签,我有一个画布可以画。

标签: delphi text


【解决方案1】:

对不起,这是所有先前答案和 cmets 的组合。但似乎 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;

【讨论】:

  • 我看不出 deamon_x 和这个版本之间的区别,但是这个工作!!!!谢谢:)
  • 这一行是关键:DT_END_ELLIPSIS 或 DT_NOPREFIX 或 DT_WORDBREAK 或 DT_EDITCONTROL 或 DT_CENTER;
  • 我知道结果很简单,但是任何其他标志组合都不起作用!如果可以的话,我会分分:)
  • @NGLN 我希望你的例子能解决我的问题,但它没有,我尝试在指定的矩形内将文本居中,但如果文本不适合并且绘制了 ELLIPSIS ,即使只清楚地绘制了 2 条线,DrawRect.Bottom 也会报告一个代表 3 条线的值。这是显示问题zoomplayer.com/pix/font_vcenter.jpg 的示例图像(文本后面较暗的区域是指定的矩形)。
  • @bLight 我认为最好针对您的具体问题提出一个新问题。
【解决方案2】:

首先使用DT_CALCRECT 测量文本。通过DT_WORDBREAK 指定启用自动换行。这将允许您找到文本所需的高度。然后,您可以在您的代码中计算使您的文本垂直居中的垂直偏移量,并绘制到该偏移量。

【讨论】:

  • 我尝试了这种方法,但由于某种原因,在指定 DT_WORDBREAK 时会忽略 DT_WORD_ELLIPSIS。此例程当前不绘制矩形之外的文本(并且不显示“...”)
  • 有没有办法可以准确地得到绘制的文本(或长度)?
  • @Simon DrawTextParams.uiLengthDrawn 返回绘制的字符数,包括由于 DT_WORD_ELLIPSIS 而产生的 3 个点。
  • @Simon - 我认为您正在寻找DT_CENTER or DT_WORDBREAK or DT_END_ELLIPSIS or DT_MODIFYSTRING 这将包裹您的文本,将其水平居中并在文本末尾显示省略号,以防最后一行无法完全显示。
  • 你不需要DT_MODIFYSTRING,它只需要在绘画之后进行文本处理。使用 DT_EDITCONTROL 仅显示完整的可见行。如果没有,则会绘制部分线条,这可能是看不到省略号的原因。
猜你喜欢
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多