如何为TLabel创建resize事件(TGraphicControl)

我正在尝试创建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;
非常感谢 :)     
已邀请:
我不认为您想要通知
TLabel
后代已经调整大小。相反,您希望收到通知,说明它缩短了文本。我知道它们看起来是一样的,但它们不是 - 标签可能仍然比文本宽,它可能有
WordWrap
开启等。此外,
TCustomLabel
后代可以使用几种不同的方法来绘制文本,基于主题/ Vista / Aero发光的东西(它们可以归结为
DrawThemeTextEx
DrawText
),所以你需要挂钩到那个系统才能确切地知道它正在绘制的文本是做什么的,包括渲染文本的大小。 如果您使用的是非入门版的Delphi,请查看
stdctrls.pas
中的
TCustomLabel
源。有两种感兴趣的方法:
TCustomLabel.AdjustBounds
- 这是设置边界矩形的地方,它可以调整自动换行等。它通过调用(如绘画)另一种感兴趣的方法来完成:
TCustomLabel.DoDrawText
- 这绘制文本和/或计算文本边界矩形,考虑椭圆,包装,这种事情。在内部,它会生成一个更改的字符串,即实际绘制的文本。换句话说,此方法的功能可以告诉您文本是否适合。 两者都是
dynamic
,它在语义上等同于
virtual
- 即,你可以覆盖它们。
DoDrawText
遗憾的是它不会返回它正在绘制的最终文本字符串 - 如果是,则可以覆盖它,调用继承的版本并将绘制的文本与真实文本进行比较。但是,您可以覆盖并重新实现它,并自己执行此操作。使用VCL代码作为指导(你需要相同的功能,虽然你不应该直接复制它,因为它是由Embarcadero拥有的。)作为
dynamic
,你的后代类的版本将由
AdjustBounds
调用。在您的代码中,当您缩短文本时,还要设置一个已缩短的标志或立即生成提示。瞧。你准确地知道什么时候缩短了:)     
我想不出比ѭ15更好的事情:   发送到窗口大小,位置,   或者在Z顺序中的位置已更改为   调用SetWindowPos的结果   功能或其他窗口管理   功能。 这看起来很理想。你有什么反对使用它?     
我认为你需要覆盖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.
    
您可以简单地覆盖
Resize
方法。但是,请注意您的代码
if Canvas.TextWidth(Caption) > Width then
不同于
TCustomLabel.DoDrawText
如何确定何时绘制椭圆,这样你可能会得到意想不到的结果。 此外,椭圆绘图也可能由字体更改,主题设置更改以及可能的一些其他事件引起。     

要回复问题请先登录注册