开发者

Calculate needed size for a TLabel

开发者 https://www.devze.com 2022-12-28 02:57 出处:网络
Ok, here\'s the problem. I have a label component in a panel. The label is aligned as alClient and has wordwrap enabled. The text can vary from one line to several lines. I would like to re-size the h

Ok, here's the problem. I have a label component in a panel. The label is aligned as alClient and has wordwrap enabled. The text can vary from one line to several lines. I would like to re-size the height of the the panel (and the label开发者_Python百科) to fit all the text.

How do I get the necessary height of a label when I know the text and the width of the panel?


You can use the TCanvas.TextRect method, along with the tfCalcRect and tfWordBreak flags :

var
  lRect : TRect;
  lText : string;

begin
  lRect.Left := 0;
  lRect.Right := myWidth;
  lRect.Top := 0;
  lRect.Bottom := 0;
  
  lText := myLabel.Caption;

  myLabel.Canvas.Font := myLabel.Font;
  myLabel.Canvas.TextRect( 
            {var} lRect, //will be modified to fit the text dimensions
            {var} lText, //not modified, unless you use the "tfModifyingString" flag
            [tfCalcRect, tfWordBreak] //flags to say "compute text dimensions with line breaks"
          );
  ASSERT( lRect.Top = 0 ); //this shouldn't have moved
  myLabel.Height := lRect.Bottom;
end;

TCanvas.TextRect wraps a call to the DrawTextEx function from the Windows API.

The tfCalcRect and tfWordBreak flags are delphi wrappers for the values DT_CALCRECT and DT_WORDBREAK of the windows API. You can find detailed information about their effects in the DrawTextEx documentation on msdn


Use TextWidth and TextHeight.

See an example here: http://www.greatis.com/delphicb/tips/lib/fonts-widthheight.html

TextWidth will tell you how wide the text would be, and then you can divide that by the control width to see how many rows you need. The remainder of the division should be an additional row.


You can use one line of code for this:

label.width := label.canvas.textwidth(label.caption);

or you can set the label's autosize property to true in the object inspector.


If you can align it alTop and keep AutoSize on then TLabel will auto adjust the height after settign the caption.


in FMX there is a trick to do that simply : when creating a Label set Autosize := true and use the OnResize Event to update the size of the parent...

Rectangle1 := TRectangle.create(Form1);
Rectangle1.parent := Form1;
Label1 := TLabel.create(Rectangle1);
Label1.parent := Rectangle1;
Label1.Align  := TAlignLayout.Top;  // keep the same width and auto size parent height
Label1.OnResize := DoReSize;
Label1.WordWrap := true;
Lable1.Autosize := true;

The parent size will be updated here (assuming that the Sender object is the most bottom control in the parent, if not you need to arrange this function to summarize all the components size and verticaly)

procedure DoParentResize(Sender : TObject);
begin
    TControl(TControl(Sender).parent).Height := TControl(Sender).Height + 4;

end;

if we use Label1.Align := TALignLayout.None;

then we should add the position inside the parent :

procedure DoParentResize(Sender : TObject);
begin
    TControl(TControl(Sender).parent).Height := TControl(Sender).Position.Y + TControl(Sender).Height + 4;

end;

Wich result in a single function for (almost) all cases :

procedure TForm1.DoParentResize(Sender : TObject);
begin
  if TControl(Sender).Align in [TAlignLayout.None, TAlignLayout.Client, TAlignLayout.Center, TAlignLayout.VertCenter ] then
  begin
    TControl(TControl(Sender).parent).Height := TControl(Sender).Position.Y + TControl(Sender).Height + 4;
  end
  else
  begin
    TControl(TControl(Sender).parent).Height := TControl(Sender).Height + 4;
  end;
end;


You need to reduce the LRect.right by the label left and right margins, and then add the label top and bottom margins to the label height at the end or the text might not fit the label.


procedure TFrm.PatternEditTyping(Sender: TObject);
begin
    (Sender as Tedit).Canvas.Font.Size := (Sender as Tedit).Font.Size;
    (Sender as Tedit).Width := (Sender as Tedit).Canvas.TextWidth((Sender as Tedit).Text);
end;

This code adjusts Tedit.Width while you type inside it. Just keep the font family in Canvas and in Tedit the same.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号