9

下面显示了字体设置为 Arial Regular 16 的默认 TLabel 的简单演示。 在此处输入图像描述

单击按钮时的代码是:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Font.Style := Label1.Font.Style + [fsItalic];
end;

单击按钮时,最后一个字符将被截断,即:

在此处输入图像描述

默认情况下, TLAbel.AutoSize 为 true,所以这应该没问题,对吧?这在 XE 和 Delphi 7 中是一样的。这是一个错误吗?

4

2 回答 2

10

最后的额外空间是解决此问题的快速解决方法。

于 2011-05-26T15:51:39.710 回答
7

是的,看起来是这样(尽管是一个相当小的错误)。可能的解决方法包括

  • TextOut使用 Windows API 函数(或)自己绘制文本DrawText,以及
  • 使用 a TStaticText(而不是 a TLabel),它只是 Windows静态控件的包装器(在文本模式下)。当然,Windows 可以正确地绘制文本。

使用TextOut

procedure TForm4.FormPaint(Sender: TObject);
const
  S = 'This is a test';
begin
  TextOut(Canvas.Handle,
    10,
    10,
    PChar(S),
    length(S));
end;

文本输出示例

使用静态控件 ( TStaticText)

静态控制样品

我猜这在 Microsoft Windows 操作系统中不是问题,而只是在 VCLTLabel控件中。

更新

我试过

procedure TForm4.FormPaint(Sender: TObject);
const
  S = 'This is a test';
var
  r: TRect;
begin
  r.Left := 10;
  r.Top := 10;
  r.Bottom := r.Top + DrawText(Canvas.Handle,
    PChar(S),
    length(S),
    r,
    DT_SINGLELINE or DT_LEFT or DT_CALCRECT);
  DrawText(Canvas.Handle,
    PChar(S),
    length(S),
    r,
    DT_SINGLELINE or DT_LEFT);
end;

结果是这样的:

绘图文本示例

因此,这毕竟是 Microsoft Windows 操作系统(或 Arial 字体)中的问题。

一种解决方法是添加DT_NOCLIP标志:

procedure TForm4.FormPaint(Sender: TObject);
const
  S = 'This is a test';
var
  r: TRect;
begin
  r.Left := 10;
  r.Top := 10;
  r.Bottom := r.Top + DrawText(Canvas.Handle,
    PChar(S),
    length(S),
    r,
    DT_SINGLELINE or DT_LEFT or DT_CALCRECT);
  DrawText(Canvas.Handle,
    PChar(S),
    length(S),
    r,
    DT_SINGLELINE or DT_LEFT or DT_NOCLIP);
end;

带有 DT_NOCLIP 示例的 DrawText

更新 2

一个轻量级的修复可能是

type
  TLabel = class(StdCtrls.TLabel)
  protected
    procedure DoDrawText(var Rect: TRect; Flags: Integer); override;
  end;

...

{ TLabel }

procedure TLabel.DoDrawText(var Rect: TRect; Flags: Integer);
begin
  inherited;
  if (Flags and DT_CALCRECT) <> 0 then
    Rect.Right := Rect.Right + 2;
end;

产生结果

TLabel 稍作修改

(但是硬编码一个神奇的值(2)似乎很讨厌......)

于 2011-05-26T15:51:19.913 回答