Delphi 从具有滚动条的组件中获得实际完整 height/Width
Delphi get actual full height/Width off a component that has scrollbar
这个问题类似于
how-to-find-the-actual-width-of-grid-component-with-scrollbar-in-delphi
但是我无法获取 CalcDrawInfo(DrawInfo);使用 StringGrid
例如,如果您添加一个 StringGrid 并在 FormCreate 中随机设置 RowCount 和 ColCount 值
你能得到这个组件的实际大小吗,这样如果你设置宽度和高度,滚动条就会消失,如果你的屏幕足够大,你可以看到所有的 StringGrid
我猜想在 StringGrid 的情况下,您可以通过遍历列获取信息并将它们相加来计算宽度和高度。
我只是想知道是否可以劫持一些东西滚动条确实会计算其位置,因此它知道要绘制组件的哪一部分,
或者一些可以 return 整个组件范围
的 Draw 函数
如果可能的话,您可以双击字符串网格来计算下面示例中的实际高度和宽度
开始新的 Delphi VCL 表单申请
复制下面并粘贴到主窗体
object strngrd1: TStringGrid
Left = 0
Top = 0
Width = 200
Height = 150
ColCount = 12
RowCount = 13
TabOrder = 0
OnDblClick = strngrd1DblClick
end
连接 FormCreate 和 StringGrid DblClick 事件
procedure TfrmMain.FormCreate(Sender: TObject);
var i, iMax : Integer;
begin
strngrd1.RowCount := Random(100);
strngrd1.ColCount := Random(100);
iMax := strngrd1.RowCount;
if strngrd1.ColCount > iMax then
iMax := strngrd1.ColCount;
for I := 0 to iMax -1 do begin
if i < strngrd1.RowCount then
strngrd1.Rows[i].Text := i.ToString;
if i < strngrd1.ColCount then
strngrd1.Cols[i].Text := i.ToString;
end;
end;
procedure TfrmMain.strngrd1DblClick(Sender: TObject);
var iActualWidth, iActualHeight : Integer;
sActualWidth, sActualHeight : String;
begin
iActualWidth := 0;
iActualHeight := 0;
sActualWidth := '??';
sActualHeight := '??';
if iActualHeight > 0 then
sActualHeight := iActualHeight.ToString;
if iActualWidth > 0 then
sActualWidth := iActualWidth.ToString;
ShowMessage(strngrd1.ClassType.ClassName + #13#10 +
'Current Width = ' + strngrd1.Width.ToString + #13#10 +
'Current Height = ' + strngrd1.Height.ToString + #13#10 +
'Client Width = ' + strngrd1.ClientWidth.ToString + #13#10 +
'Client Height = ' + strngrd1.ClientHeight.ToString + #13#10 +
'Actual Width = ' + sActualWidth + #13#10 +
'Actual Height = ' + sActualHeight + #13#10 );
end;
双击 return 组件的实际范围,以便在重置宽度和高度后滚动条不再可见
不幸的是,您需要的方法 (CalcDrawInfoXY
) 已在 TCustomGrid
中声明为 private
。复制它很简单,但是:
声明一个 hack class 来暴露 CalcFixedInfo
,介绍你自己的方法来复制 CalcDrawInfoXY
。
TGridHack = class(TCustomGrid)
procedure GetDrawInfoXY(var DrawInfo: TGridDrawInfo; UseWidth, UseHeight: Integer);
end;
并实施为(来自 Vcl.Grids)
procedure TGridHack.GetDrawInfoXY(var DrawInfo: TGridDrawInfo;
UseWidth, UseHeight: Integer);
procedure CalcAxis(var AxisInfo: TGridAxisDrawInfo; UseExtent: Integer);
var
I: Integer;
begin
with AxisInfo do
begin
GridExtent := UseExtent;
GridBoundary := FixedBoundary;
FullVisBoundary := FixedBoundary;
LastFullVisibleCell := FirstGridCell;
for I := FirstGridCell to GridCellCount - 1 do
begin
Inc(GridBoundary, AxisInfo.GetExtent(I) + EffectiveLineWidth);
if GridBoundary > GridExtent + EffectiveLineWidth then
begin
GridBoundary := GridExtent;
Break;
end;
LastFullVisibleCell := I;
FullVisBoundary := GridBoundary;
end;
end;
end;
begin
CalcFixedInfo(DrawInfo);
CalcAxis(DrawInfo.Horz, UseWidth);
CalcAxis(DrawInfo.Vert, UseHeight);
end;
这允许您获得 TGridDrawInfo
假想的 canvas 尺寸。使用适当大的虚数 canvas 您可以获得网格的完整范围:
procedure TForm1.strngrd1DblClick(Sender: TObject);
var iActualWidth, iActualHeight : Integer;
sActualWidth, sActualHeight : String;
DrawInfo : TGridDrawInfo;
begin
TGridHack(strngrd1).GetDrawInfoXY(DrawInfo, MaxInt - 1, MaxInt - 1);
iActualWidth := DrawInfo.Horz.GridBoundary;
iActualHeight := DrawInfo.Vert.GridBoundary;
sActualWidth := iActualWidth.ToString;
sActualHeight := iActualHeight.ToString;
ShowMessage(strngrd1.ClassType.ClassName + #13#10 +
'Current Width = ' + strngrd1.Width.ToString + #13#10 +
'Current Height = ' + strngrd1.Height.ToString + #13#10 +
'Client Width = ' + strngrd1.ClientWidth.ToString + #13#10 +
'Client Height = ' + strngrd1.ClientHeight.ToString + #13#10 +
'Actual Width = ' + sActualWidth + #13#10 +
'Actual Height = ' + sActualHeight + #13#10 );
end;
我在这里使用了 MaxInt - 1
,它应该足够大以容纳几乎所有理智的东西。 MaxInt
不能用作参数,如果您这样做,DrawInfo
将 return MaxInt
作为网格大小。这实际上是按照您在问题中提出的建议进行操作,即遍历行和列以测量网格的总大小。
这个问题类似于 how-to-find-the-actual-width-of-grid-component-with-scrollbar-in-delphi
但是我无法获取 CalcDrawInfo(DrawInfo);使用 StringGrid
例如,如果您添加一个 StringGrid 并在 FormCreate 中随机设置 RowCount 和 ColCount 值
你能得到这个组件的实际大小吗,这样如果你设置宽度和高度,滚动条就会消失,如果你的屏幕足够大,你可以看到所有的 StringGrid
我猜想在 StringGrid 的情况下,您可以通过遍历列获取信息并将它们相加来计算宽度和高度。
我只是想知道是否可以劫持一些东西滚动条确实会计算其位置,因此它知道要绘制组件的哪一部分,
或者一些可以 return 整个组件范围
如果可能的话,您可以双击字符串网格来计算下面示例中的实际高度和宽度
开始新的 Delphi VCL 表单申请
复制下面并粘贴到主窗体
object strngrd1: TStringGrid
Left = 0
Top = 0
Width = 200
Height = 150
ColCount = 12
RowCount = 13
TabOrder = 0
OnDblClick = strngrd1DblClick
end
连接 FormCreate 和 StringGrid DblClick 事件
procedure TfrmMain.FormCreate(Sender: TObject);
var i, iMax : Integer;
begin
strngrd1.RowCount := Random(100);
strngrd1.ColCount := Random(100);
iMax := strngrd1.RowCount;
if strngrd1.ColCount > iMax then
iMax := strngrd1.ColCount;
for I := 0 to iMax -1 do begin
if i < strngrd1.RowCount then
strngrd1.Rows[i].Text := i.ToString;
if i < strngrd1.ColCount then
strngrd1.Cols[i].Text := i.ToString;
end;
end;
procedure TfrmMain.strngrd1DblClick(Sender: TObject);
var iActualWidth, iActualHeight : Integer;
sActualWidth, sActualHeight : String;
begin
iActualWidth := 0;
iActualHeight := 0;
sActualWidth := '??';
sActualHeight := '??';
if iActualHeight > 0 then
sActualHeight := iActualHeight.ToString;
if iActualWidth > 0 then
sActualWidth := iActualWidth.ToString;
ShowMessage(strngrd1.ClassType.ClassName + #13#10 +
'Current Width = ' + strngrd1.Width.ToString + #13#10 +
'Current Height = ' + strngrd1.Height.ToString + #13#10 +
'Client Width = ' + strngrd1.ClientWidth.ToString + #13#10 +
'Client Height = ' + strngrd1.ClientHeight.ToString + #13#10 +
'Actual Width = ' + sActualWidth + #13#10 +
'Actual Height = ' + sActualHeight + #13#10 );
end;
双击 return 组件的实际范围,以便在重置宽度和高度后滚动条不再可见
不幸的是,您需要的方法 (CalcDrawInfoXY
) 已在 TCustomGrid
中声明为 private
。复制它很简单,但是:
声明一个 hack class 来暴露 CalcFixedInfo
,介绍你自己的方法来复制 CalcDrawInfoXY
。
TGridHack = class(TCustomGrid)
procedure GetDrawInfoXY(var DrawInfo: TGridDrawInfo; UseWidth, UseHeight: Integer);
end;
并实施为(来自 Vcl.Grids)
procedure TGridHack.GetDrawInfoXY(var DrawInfo: TGridDrawInfo;
UseWidth, UseHeight: Integer);
procedure CalcAxis(var AxisInfo: TGridAxisDrawInfo; UseExtent: Integer);
var
I: Integer;
begin
with AxisInfo do
begin
GridExtent := UseExtent;
GridBoundary := FixedBoundary;
FullVisBoundary := FixedBoundary;
LastFullVisibleCell := FirstGridCell;
for I := FirstGridCell to GridCellCount - 1 do
begin
Inc(GridBoundary, AxisInfo.GetExtent(I) + EffectiveLineWidth);
if GridBoundary > GridExtent + EffectiveLineWidth then
begin
GridBoundary := GridExtent;
Break;
end;
LastFullVisibleCell := I;
FullVisBoundary := GridBoundary;
end;
end;
end;
begin
CalcFixedInfo(DrawInfo);
CalcAxis(DrawInfo.Horz, UseWidth);
CalcAxis(DrawInfo.Vert, UseHeight);
end;
这允许您获得 TGridDrawInfo
假想的 canvas 尺寸。使用适当大的虚数 canvas 您可以获得网格的完整范围:
procedure TForm1.strngrd1DblClick(Sender: TObject);
var iActualWidth, iActualHeight : Integer;
sActualWidth, sActualHeight : String;
DrawInfo : TGridDrawInfo;
begin
TGridHack(strngrd1).GetDrawInfoXY(DrawInfo, MaxInt - 1, MaxInt - 1);
iActualWidth := DrawInfo.Horz.GridBoundary;
iActualHeight := DrawInfo.Vert.GridBoundary;
sActualWidth := iActualWidth.ToString;
sActualHeight := iActualHeight.ToString;
ShowMessage(strngrd1.ClassType.ClassName + #13#10 +
'Current Width = ' + strngrd1.Width.ToString + #13#10 +
'Current Height = ' + strngrd1.Height.ToString + #13#10 +
'Client Width = ' + strngrd1.ClientWidth.ToString + #13#10 +
'Client Height = ' + strngrd1.ClientHeight.ToString + #13#10 +
'Actual Width = ' + sActualWidth + #13#10 +
'Actual Height = ' + sActualHeight + #13#10 );
end;
我在这里使用了 MaxInt - 1
,它应该足够大以容纳几乎所有理智的东西。 MaxInt
不能用作参数,如果您这样做,DrawInfo
将 return MaxInt
作为网格大小。这实际上是按照您在问题中提出的建议进行操作,即遍历行和列以测量网格的总大小。