确定 TLabel 的宽度
Determine Width of TLabel
你好 Stack Overflow 用户
我有一个 TGroupBox
,里面有一个 TLabel
。使用此 TLabel
我想显示候选人的姓氏和姓名。有些候选人有不止一个名字,有时是三个,当发生这种情况时,TLabel
并不总是适合我的 TGroupBox
。发生这种情况时,我只显示姓氏和名字,其余的我只显示为首字母。
为此,我需要知道 TLabel
是否适合分配值。换句话说,我需要在实际将值分配给它的 Caption
属性 之前确定 TLabel
的宽度,因为那将是显示可变数据的糟糕编程.
有什么建议吗?
在 VCL 中,TLabel
使用 Win32 API DrawText()
function to calculate the text width, using GetDC()
to get the HDC
of the screen and then SelectObject()
将其当前 Font
select 转换为 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;
如果您想将长文本换行成多行,那么您可以使用标签的 属性 WordWrap := True
和 AutoSize := True
.
我找到了一种非常简单快捷的方法来做到这一点。基本上,您只想知道字符串的宽度(以像素为单位),因此实现此目的的最佳方法是动态创建一个具有 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;
你好 Stack Overflow 用户
我有一个 TGroupBox
,里面有一个 TLabel
。使用此 TLabel
我想显示候选人的姓氏和姓名。有些候选人有不止一个名字,有时是三个,当发生这种情况时,TLabel
并不总是适合我的 TGroupBox
。发生这种情况时,我只显示姓氏和名字,其余的我只显示为首字母。
为此,我需要知道 TLabel
是否适合分配值。换句话说,我需要在实际将值分配给它的 Caption
属性 之前确定 TLabel
的宽度,因为那将是显示可变数据的糟糕编程.
有什么建议吗?
在 VCL 中,TLabel
使用 Win32 API DrawText()
function to calculate the text width, using GetDC()
to get the HDC
of the screen and then SelectObject()
将其当前 Font
select 转换为 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;
如果您想将长文本换行成多行,那么您可以使用标签的 属性 WordWrap := True
和 AutoSize := True
.
我找到了一种非常简单快捷的方法来做到这一点。基本上,您只想知道字符串的宽度(以像素为单位),因此实现此目的的最佳方法是动态创建一个具有 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;