Reginald Greyling
Reginald Greyling

Reputation: 373

Determine Width of TLabel

Hello Stack Overflow Users

I have a TGroupBox with a TLabel in it. With this TLabel I want to display the surname and names of a candidate. Some candidates have more than one name, sometimes three, and when that happens, the TLabel doesn't always fit inside my TGroupBox. When that happens, I only display the surname, the first name, and the rest I only as initials.

In order to do this, I need to know whether the TLabel is going to fit if the values were to be assigned to it. In other words, I need to determine what the width of the TLabel is going to be before actually assigning the values to its Caption property, for that would be bad programming to display variable data.

Any suggestions?

Upvotes: 2

Views: 2168

Answers (3)

Reginald Greyling
Reginald Greyling

Reputation: 373

I found a very easy and short way to do this. Basically, you just want to know the width of a string in pixels, so the best way to achieve this is to dynamically create an object that has a Font and Canvas property. I thought TBitmap will be the best option. Here’s the code I used:

var
  sString: string;
  bmWidth: TBitmap;
  iWidth: Integer;
begin
  sString := edtEdit.Text;
  bmWidth := TBitmap.Create;
  try
    bmWidth.Canvas.Font.Assign(lblLabel.Font);
    iWidth := bmWidth.Canvas.TextWidth(sString);
  finally
    bmWidth.Free;
  end;
end;

Upvotes: 3

JayDi
JayDi

Reputation: 1067

If you want wrapping long text in multi lines then you can use label's property WordWrap := True and AutoSize := True.

Upvotes: -1

Remy Lebeau
Remy Lebeau

Reputation: 597941

In VCL, TLabel uses the Win32 API DrawText() function to calculate the text width, using GetDC() to get the HDC of the screen and then SelectObject() to select its current Font into that HDC. You will have to do the same in your own code, eg:

// set Label1.AutoSize to False and Label1.Width to
// the max width your UI will accept the Label1 to be...

function WillFitInLabel(Label: TLabel; const S: String): Boolean;
var
  R: TRect;
  C: TCanvas;
  DC: HDC;
begin
  R := Rect(0, 0, Label.Width, 0);
  C := TCanvas.Create;
  try
    DC := GetDC(0);
    try
      C.Handle := DC;
      try
        C.Font := Label1.Font;
        Windows.DrawText(DC, PChar(S), Length(S), R, DT_SINGLELINE or DT_CALCRECT);
      finally
        C.Handle := 0;
      end;
    finally
      ReleaseDC(0, DC);
    end;
  finally
    C.Free;
  end;
  Result := (R.Width <= Label.Width);
end;

var
  Names: String;
begin
  Names := ...;
  if WillFitInLabel(Label1, Names) then
    Label1.Caption := Names
  else
    ...
end;

Upvotes: 1

Related Questions