1

你好堆栈溢出用户

我有TGroupBox一个TLabel在里面。有了这个TLabel,我想显示候选人的姓氏和名字。有些候选人有不止一个名字,有时三个,当这种情况发生时,TLabel并不总是适合我的TGroupBox. 发生这种情况时,我只显示姓氏、名字,其余的只显示为首字母。

为了做到这一点,我需要知道TLabel如果要为其分配值,它是否适合。换句话说,TLabel在将值实际分配给它的Caption属性之前,我需要确定它的宽度,因为那将是显示可变数据的糟糕编程。

有什么建议么?

4

3 回答 3

1

在 VCL 中,TLabel使用 Win32 APIDrawText()函数计算文本宽度,使用GetDC()获取HDC屏幕的 ,然后SelectObject() 将其当前选择FontHDC. 您必须在自己的代码中执行相同的操作,例如:

// 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;
于 2015-09-30T17:23:45.087 回答
1

我找到了一种非常简单快捷的方法来做到这一点。基本上,您只想知道字符串的宽度(以像素为单位),因此实现此目的的最佳方法是动态创建一个具有FontandCanvas属性的对象。我认为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;
于 2015-10-03T14:08:52.843 回答
0

如果你想在多行中包装长文本,那么你可以使用标签的属性WordWrap := TrueAutoSize := True.

于 2015-10-02T15:34:57.027 回答