Определить ширину TLabel

Привет, пользователи переполнения стека

у меня есть TGroupBox с TLabel в этом. С этим TLabel Я хочу отобразить фамилию и имена кандидата. Некоторые кандидаты имеют более одного имени, иногда три, и когда это происходит, TLabel не всегда вписывается в мой TGroupBox, Когда это происходит, я только отображаю фамилию, имя, а остальные я только в качестве инициалов.

Для этого мне нужно знать, TLabel будет соответствовать, если значения должны быть назначены ему. Другими словами, мне нужно определить, какая ширина TLabel будет до того, как на самом деле присвоение значений его Caption свойство, для этого было бы плохое программирование для отображения переменных данных.

Какие-либо предложения?

3 ответа

Решение

Я нашел очень простой и короткий способ сделать это. По сути, вы просто хотите узнать ширину строки в пикселях, поэтому лучший способ добиться этого - динамически создать объект, имеющий Font а также Canvas имущество. я думал TBitmap будет лучшим вариантом. Вот код, который я использовал:

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;

В VCL, TLabel использует Win32 API DrawText() функция для расчета ширины текста, используя GetDC() чтобы получить HDC экрана, а затем SelectObject() выбрать его текущий Font в это HDC, Вам придется сделать то же самое в своем собственном коде, например:

// 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;

Если вы хотите обернуть длинный текст в несколько строк, вы можете использовать свойство label WordWrap := True а также AutoSize := True,

Другие вопросы по тегам