1

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;

どうもありがとう :)

4

4 に答える 4

1

私はこれ以上のことは考えられませんWM_WINDOWPOSCHANGED

SetWindowPos関数または別のウィンドウ管理関数を呼び出した結果、Zオーダーのサイズ、位置、または位置が変更されたウィンドウに送信されます。

それは理想的に見えます。あなたはそれを使うことに対して何がありますか?

于 2011-03-10T16:17:13.863 に答える
1

TLabel子孫のサイズが変更 されたことを通知されたくないと思います。代わりに、テキストが短縮されたことを通知する必要があります。同じように見えますが、そうではありません。ラベルはテキストよりも幅が広い場合や、WordWrapオンになっている場合などがあります。さらに、TCustomLabel子孫は、テーマに基づいて、いくつかの異なる方法を使用してテキストを描画できます。 Vista / Aeroグローのもの(要約するとDrawThemeTextExDrawText)なので、そのシステムに接続して、レンダリングされたテキストのサイズなど、描画しているテキストが何をしているのかを正確に知る必要があります。

Delphiの非スターターエディションを使用している場合は、のTCustomLabelソースを参照してくださいstdctrls.pas。関心のある2つの方法があります。

  • TCustomLabel.AdjustBounds-これは、境界矩形が設定される場所であり、ワードラップなどを調整します。これは、(ペイントと同様に)他の対象のメソッドを呼び出すことによって行われます。
  • TCustomLabel.DoDrawText-これは、テキストをペイントしたり、楕円や折り返しなどを考慮したテキスト境界の長方形を計算したりします。 内部的には、実際に描画されるテキストである変更された文字列を生成します。 つまり、このメソッドの機能は、テキストが収まるかどうかを示します。

どちらもですdynamic。これは意味的には存在することと同じvirtualです。つまり、それらをオーバーライドできます。

DoDrawText残念ながら、ペイントしている最終的なテキスト文字列は返されません。返される場合は、オーバーライドして、継承されたバージョンを呼び出し、ペイントされたテキストを実際のテキストと比較できます。ただし、それをオーバーライドして再実装し、これを自分で行うことができます。VCLコードをガイドとして使用します(同等の機能が必要ですが、Embarcaderoが所有しているため、直接コピーしないdynamicでください)。したがって、子孫クラスのバージョンはによって呼び出されAdjustBoundsます。コードでは、テキストを短縮するときに、短縮されたフラグを設定するか、すぐにヒントを生成します。出来上がり。あなたはそれがいつ短縮されたかを正確に知っています:)

于 2011-03-10T23:14:08.683 に答える
0

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.
于 2011-03-10T16:19:15.033 に答える
0

Resizeメソッドをオーバーライドするだけです。ただし、コードに注意してください

if Canvas.TextWidth(Caption) > Width then

楕円を描画するタイミングを決定する方法とは異なるTCustomLabel.DoDrawTextため、予期しない結果が生じる可能性があります。

また、楕円の描画は、フォントの変更、テーマ設定の変更、およびその他のイベントによっても発生する可能性があります。

于 2011-03-10T16:47:59.187 に答える