【问题标题】:How to create resize event for TLabel (TGraphicControl)如何为 TLabel (TGraphicControl) 创建调整大小事件
【发布时间】:2011-03-10 14:27:24
【问题描述】:

我正在尝试创建 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;

非常感谢 :)

【问题讨论】:

  • 可以覆盖SetBounds,这是执行WM_WINDOWPOSCHANGED的地方。或者,如果您希望将代码放入事件处理程序中,您可以简单地发布后代的 OnResize 属性。看不出任何一个比消息处理程序更好的理由......

标签: delphi winapi resize notifications tlabel


【解决方案1】:

我认为您不希望收到 TLabel 后代已调整大小的通知。 相反,您希望收到通知,它已缩短了文本。我知道它们看起来一样,但它们不是——标签可能仍然比文本宽,它可能打开了WordWrap,等等。此外,TCustomLabel 后代可以使用几种不同的方法来绘制文本,基于主题/Vista/Aero 发光的东西(它们归结为 DrawThemeTextExDrawText),因此您需要连接到该系统以准确了解它正在绘制的文本在做什么,包括呈现的文本是。

如果您使用的是 Delphi 的非 Starter 版本,请查看 stdctrls.pas 中的 TCustomLabel 源代码。有两种感兴趣的方法:

  • TCustomLabel.AdjustBounds - 这是设置边界矩形的地方,它会针对自动换行等进行调整。它通过调用(与绘画一样)其他感兴趣的方法来做到这一点:
  • TCustomLabel.DoDrawText - 这会绘制文本和/或计算文本边界矩形,以考虑椭圆、环绕等。 在内部,它会生成一个更改后的字符串,即实际绘制的文本。换句话说,此方法的功能是告诉您文本是否适合。

两者都是dynamic,在语义上等同于virtual - 即,您可以覆盖它们。

DoDrawText 不幸的是,它没有返回它正在绘制的最终文本字符串 - 如果它返回了,您可以覆盖它,调用继承的版本并将绘制的文本与真实文本进行比较。但是,您可以覆盖并重新实现它,并自己执行此操作。使用 VCL 代码作为指导(您需要等效的功能,尽管您不应该直接复制它,因为它归 Embarcadero 所有。)作为dynamic,您的后代类的版本将由AdjustBounds 调用。在您的代码中,当您缩短文本时,还要设置一个已缩短的标志或立即生成提示。瞧。您准确地知道它何时被缩短:)

【讨论】:

  • 没错,当我的 TLabel 被 epEndEllipsis 三点字符串缩短时,我需要得到通知,但是该怎么做呢?
  • 我回答的最后一段应该解释这一点(具体来说,“覆盖并重新实现它......当你缩短文本时,还要设置一个标志它已被缩短或......”)。其中有什么你不明白/我可以为你扩展吗?
【解决方案2】:

我想不出比WM_WINDOWPOSCHANGED更好的东西了:

发送到一个窗口,其大小、位置、 或 Z 顺序中的位置已更改为 调用 SetWindowPos 的结果 功能或其他窗口管理 功能。

这看起来很理想。你有什么反对使用它的?

【讨论】:

  • 事实上,它被调用得太早(在知道父级之前)并且我需要携带父级分配,否则我会遇到访问冲突,所以我要求一些特定的消息或方法'不需要此检查,仅在更改大小时调用。
  • Parent 分配的时候不能只做需要Parent 分配的工作吗?
  • 是的,但我希望有像 WM_EXITSIZEMOVE 这样的东西,当控件完成调整大小时,可能只调用一次。
  • 他真的不想检查文本何时缩短,而不是标签调整大小时检查吗?调整大小可能根本不会改变显示的文本。
  • @David M - 是的,他这样做了:) 但是你会怎么做呢?我想在缩短文本时显示带有整个标题的提示,仅此而已
【解决方案3】:

我认为您需要重写 AdjustBounds 方法。试试下面的代码(只需创建一个带有 TButtonTLabel 的表单,并用此代码替换 .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.

【讨论】:

  • 我认为 OP 没有使用 AutoSize。如果是这样,那么为什么需要省略号?
  • @David - 你是对的,但无论如何 AdjustBounds 也可能是解决方案。
【解决方案4】:

您可以简单地覆盖Resize 方法。但是,请注意您的代码

if Canvas.TextWidth(Caption) > Width then

TCustomLabel.DoDrawText 确定何时绘制椭圆的方式不同,因此您可能会得到意想不到的结果。

此外,椭圆的绘制也可能是由字体更改、主题设置更改以及其他一些事件引起的。

【讨论】:

  • 我同意你的观点,但在我的情况下,以这种方式计算宽度就足够了,因为字体是独立于主题的(我希望 :) 并且标签上没有框架。并且提到的 Resize 方法对我来说看起来不错 - 我会尽快检查它。我已经想到了字体更改,但这永远不会发生,对我来说重要的是只有文本更改和调整大小:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 2019-02-01
  • 2022-10-01
  • 2011-12-26
  • 2013-06-22
  • 2015-10-04
相关资源
最近更新 更多