将Delphi TLabel的字体改为斜体将尾部切掉-为什么?
下面是字体设置为Arial Regular 16的默认TLabel的简单演示。 单击按钮时的代码为:将Delphi TLabel的字体改为斜体将尾部切掉-为什么?,delphi,fonts,autosize,italic,tlabel,Delphi,Fonts,Autosize,Italic,Tlabel,下面是字体设置为Arial Regular 16的默认TLabel的简单演示。 单击按钮时的代码为: procedure TForm1.Button1Click(Sender: TObject); begin Label1.Font.Style := Label1.Font.Style + [fsItalic]; end; 单击按钮时,最后一个字符被截断,即: 默认情况下,TLAbel.AutoSize为true,所以这应该可以,对吗?这在XE和Delphi7中是相同的。这是虫子吗 是
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Font.Style := Label1.Font.Style + [fsItalic];
end;
单击按钮时,最后一个字符被截断,即:
默认情况下,TLAbel.AutoSize为true,所以这应该可以,对吗?这在XE和Delphi7中是相同的。这是虫子吗 是的,看起来是这样(虽然是一个相当小的bug)。可能的解决办法包括
- 使用Windows API函数(或)自己绘制文本,然后
- 使用(而不是
),它只是窗口的包装器(在文本模式下)。当然,Windows可以正确地绘制文本TLabel
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;
更新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=class(StdCtrls.TLabel)
受保护的
过程DoDrawText(变量Rect:TRect;标志:整数);推翻
结束;
...
{TLabel}
过程TLabel.DoDrawText(var Rect:TRect;标志:Integer);
开始
继承;
如果(Flags和DT_calcorrect)为0,则
右矩形:=右矩形+2;
结束;
产生结果
(但是硬编码一个神奇的值(2)似乎很讨厌……在末尾加上一个额外的空格可以很快解决这个问题。我不相信这是一个Delphi错误,因为它只影响Arial。至少它不会影响Tahoma或Segoe用户界面,这是更常用的用户界面字体。我猜是Windows或字体本身出了问题。@Brian:请注意,在运行时不需要添加
fsItalic
,就可以显示此问题。您可以在IDE中将FontStyle
设置为[fsItalic]
。@andreas:我知道,谢谢。这是为了实现我使用的一个主题化例程。当AutoSize为true时,Delphi要求操作系统扩展文本,这看起来确实像Windows中的一个bug。结果似乎是错的。@Uwe:信不信由你,我认为你是对的。请看下面我的实验。TStaticText是最好的解决方法。不仅仅是因为它还可以解决调整复杂表单大小时出现的闪烁问题。这有点像是有文档记录的:“请注意,具有显著突出部分的文本可能会被剪裁,例如,文本字符串中的首字母“W”或斜体文本”。From@David:TStaticText
的缺点是,与TLabel
不同,它使用Windows句柄。通常情况下,在32/64位Windows下这不是问题,但当内存/资源可能很紧张时,需要记住这一点。@Ken:是的,但从新千年开始,这就不是问题了。@TLabel的缺点是在调整大小时会出现可怕的闪烁。我已经在自动调整大小的网格单元+1中使用了该修复程序,并接受了该程序,因为它适用于所有现有代码。TStaticText是个不错的主意,但在TRzPanel上不显示透明:-(