我正在尝试创建TLabel后代,当文本宽度超过标签宽度时,将显示整个标题的提示。我已将EllipsisPosition属性设置为epEndEllipsis,并且我的标题在结尾处自动缩写为省略号。没关系。
然而我需要收到通知,已缩短文字以设置提示。在我的情况下,这可能只在文本被更改(消息CM_TEXTCHANGED)和组件调整大小时发生。
这是我的问题 - 我如何得到通知,我的TLabel已经调整大小了?我有锚点,所以它与表单一起调整大小,但是我想把它包装好单独的TLabel后裔。
此代码有效,但有没有更好的方法?像WM_EXITSIZEMOVE,但是为TGraphicControl工作?
procedure TEllipsisLabel.WMWindowPosChanged(var Message: TWMWindowPosChanged);
begin
inherited;
if Assigned(Parent) then
if Canvas.TextWidth(Caption) > Width then
begin
ShowHint := True;
Hint := Caption;
end
else
begin
ShowHint := False;
Hint := '';
end;
end;
非常感谢:)
答案 0 :(得分:1)
我想不出比WM_WINDOWPOSCHANGED
更好的东西:
发送到一个大小,位置, 或者在Z顺序中的位置已更改为 调用SetWindowPos的结果 功能或其他窗口管理 功能
看起来很理想。你对使用它有什么看法?
答案 1 :(得分:1)
我认为您不希望收到TLabel
后代已调整大小的通知。 相反,您希望收到通知,说明它缩短了文字。我知道它们看起来是一样的,但它们不是 - 标签可能仍然比文本宽,它可能会WordWrap
打开,等等。此外,TCustomLabel
后代可以使用几个根据主题/ Vista / Aero发光内容(它们归结为DrawThemeTextEx
和DrawText
)绘制文本的不同方法,因此您需要挂钩到该系统以确切知道它所绘制的文本是什么做,包括渲染文本的大小。
如果您使用的是非简化版的Delphi,请查看TCustomLabel
中的stdctrls.pas
来源。有两种感兴趣的方法:
TCustomLabel.AdjustBounds
- 这是设置边界矩形的地方,它可以调整自动换行等。它通过调用(如同绘画)其他感兴趣的方法来实现:TCustomLabel.DoDrawText
- 这会绘制文本和/或计算文本边界矩形,说明省略号,包装,这种事情。 在内部,它会生成一个更改的字符串,即实际绘制的文本。换句话说,此方法的功能可以告诉您文本是否适合。两者都是dynamic
,在语义上等同于virtual
- 即,您可以覆盖它们。
DoDrawText
没有返回它正在绘制的最终文本字符串 - 如果是,则可以覆盖它,调用继承的版本并将绘制的文本与真实文本进行比较。但是,您可以覆盖并重新实现它,并自己执行此操作。使用VCL代码作为指导(您需要等效的功能,但不应该直接复制它,因为它由Embarcadero拥有。)作为dynamic
,您的后代类的版本将由AdjustBounds
调用。在您的代码中,当您缩短文本时,还要设置一个已缩短的标志或立即生成提示。瞧。您可以准确地确切知道它何时被缩短:)
答案 2 :(得分:0)
我认为您需要覆盖 AdjustBounds 方法。请尝试以下代码(只需在其上创建一个包含 TButton 和 TLabel 的表单,并使用此代码替换 .pas )。此示例演示如果文本更改,则检测标签大小更改。您需要创建自己的活动。
unit unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TSizeNotifyLabel = class(TLabel)
public
procedure AdjustBounds; override;
end;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
SizeNotifyLabel: TSizeNotifyLabel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
procedure TSizeNotifyLabel.AdjustBounds;
begin
inherited;
form1.label1.caption := 'Width of Label:'+inttostr(form1.SizeNotifyLabel.Width);
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
SizeNotifyLabel.Caption := SizeNotifyLabel.Caption + ' Change My Size';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SizeNotifyLabel := TSizeNotifyLabel.Create(self);
with SizeNotifyLabel do begin
caption := 'Hello World';
left := 10;
top := 10;
autosize := true;
parent := self;
end;
end;
end.
答案 3 :(得分:0)
您可以简单地覆盖Resize
方法。但是,请注意您的代码
if Canvas.TextWidth(Caption) > Width then
与TCustomLabel.DoDrawText
确定何时绘制省略号的方式不同,因此您可能会得到意外的结果。
此外,椭圆绘图也可能是由字体更改,主题设置更改以及其他一些事件引起的。