Delphi-X个组件数量后的TScrollBox问题
我注意到在我的一个测试应用程序中,当我向TScrollBox添加了如此多的Tpanel后,我遇到了一个问题,即超过一定数量的Tpanel。我在绘图之前禁用了滚动框,并且在绘图之前它总是被清除,因此没有相对位置问题。起初我想我可能已经达到了绘画的最高高度。因此,您知道这种排列方式占用了垂直堆叠的面板的宽度 因此,我创建了一个新项目来尝试识别和解决这个问题,它揭示了问题的更多细节。当我在家时,我可以提供一个例子和一个视频,但我现在将描述。使用TScrollBox和spinedit创建一个表单,以指定一个按钮在循环中创建面板的数量,以及一个按钮释放面板并清空阵列以进行另一次尝试。我将标题设置为循环中的数字,以便识别 我尝试了两种堆叠方式,看看比特是否重要。一个是设置位置I乘以高度,如果高度是200,那么I*202给它一个2px的空间。我尝试的新方法是使用align top。它的效果可能略有不同,但总的来说问题仍然是一样的 新问题在于滚动范围。循环完成并启用滚动框后,向下滚动至最后编号面板的底部止点。但它的位置可能是199,它的200个面板正下方169。然后滚动条调整范围,让我到达底部,只看到下一个最后一个面板198。我相信这是使用align top方法实现的,因为它从未在我的应用程序中出现过。我会进一步测试 底部面板不放在一边我认为解决这个问题的办法是手动计算和设置范围 在我的应用程序中,当设置位置而不是使用align top时,出现的主要问题是,经过一定数量的面板后,它们都位于同一位置的末端。在一定数量的罚款之前,比如说50或100,但在这么多之后,就发生了。我知道200乘以200是一个很小的整数,但可能有地址限制Delphi-X个组件数量后的TScrollBox问题,delphi,delphi-2009,Delphi,Delphi 2009,我注意到在我的一个测试应用程序中,当我向TScrollBox添加了如此多的Tpanel后,我遇到了一个问题,即超过一定数量的Tpanel。我在绘图之前禁用了滚动框,并且在绘图之前它总是被清除,因此没有相对位置问题。起初我想我可能已经达到了绘画的最高高度。因此,您知道这种排列方式占用了垂直堆叠的面板的宽度 因此,我创建了一个新项目来尝试识别和解决这个问题,它揭示了问题的更多细节。当我在家时,我可以提供一个例子和一个视频,但我现在将描述。使用TScrollBox和spinedit创建一个表单,以指定
我将继续测试,我仍然需要检查面板高度是否增加到它。但我认为这是一个已知的问题。顺便说一下,Delphi 2009。这是一个Windows限制:窗口控件的大小不能超过65535像素 请参阅有关的文档,其中宽度和高度在单个32位参数中一起传递: lParam LPRAM的低位字指定客户端区域的新宽度 lParam的高阶字指定客户端区域的新高度 因此,宽度和高度值限制为16位。也就是说:当涉及或类似时,它由
SetBounds
调用,通过设置Top
调用
随后,控件的Top
值(可以是负值)被限制为15位和1个符号位,因此为+-32767。具体来说:这就是Control.ClientOrigin.X/Y
的绑定位置。例如,在1920x1200像素屏幕中间放置的控件中,最大分辨率<代码>顶部<代码>值为32167。
这就是为什么最后的面板会出现在滚动框中的同一点上
请注意,此限制不适用于没有Windows句柄的VCL控件
如何解决? 滚动框中的子控件的
Top
属性与框的可见clientrect相关;滚动滚动条可重置所有子项的Top
属性
所以(就在)达到魔法极限之前,通过滚动滚动框愚弄Windows:
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
J: Integer;
P: TPanel;
begin
ScrollBox1.DisableAlign;
try
ScrollBox1.VertScrollBar.Range := 400 * 202; // 80,800 ! ;-)
for I := 0 to 3 do
begin
ScrollBox1.VertScrollBar.Position := I * 100 * 202;
for J := 0 to 99 do
begin
P := TPanel.Create(Self);
P.SetBounds(0, J * 202, 100, 200);
P.Align := alCustom;
P.Caption := IntToStr(I * 100 + J);
P.ParentBackground := False;
P.Color := Random(clWhite);
P.Parent := ScrollBox1;
end;
end;
finally
ScrollBox1.VertScrollBar.Position := 0;
ScrollBox1.EnableAlign;
end;
end;
如何更好地解决这个问题? 使用
TControl
衍生工具来绕过对SetWindowPos
的API调用,而不是TPanel
(aTWinControl
)
如何最好地解决它?
使用虚拟方法,如
TDBControlGrid
所做的那样,只显示少数面板,同时给人留下拥有大量面板的印象。这是Windows限制:窗口控件的大小不能超过65535像素
请参阅有关的文档,其中宽度和高度在单个32位参数中一起传递:
lParam
LPRAM的低位字指定客户端区域的新宽度
lParam的高阶字指定客户端区域的新高度
因此,宽度和高度值限制为16位。也就是说:当涉及或类似时,它由SetBounds
调用,通过设置Top
调用
随后,控件的Top
值(可以是负值)被限制为15位和1个符号位,因此为+-32767。具体来说:这就是Control.ClientOrigin.X/Y
的绑定位置。例如,在1920x1200像素屏幕中间放置的控件中,最大分辨率<代码>顶部<代码>值为32167。
这就是为什么最后的面板会出现在滚动框中的同一点上
请注意,此限制不适用于没有Windows句柄的VCL控件
如何解决? 滚动框中的子控件的
Top
属性与框的可见clientrect相关;滚动滚动条可重置所有子项的Top
属性
所以(就在)达到魔法极限之前,通过滚动滚动框愚弄Windows:
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
J: Integer;
P: TPanel;
begin
ScrollBox1.DisableAlign;
try
ScrollBox1.VertScrollBar.Range := 400 * 202; // 80,800 ! ;-)
for I := 0 to 3 do
begin
ScrollBox1.VertScrollBar.Position := I * 100 * 202;
for J := 0 to 99 do
begin
P := TPanel.Create(Self);
P.SetBounds(0, J * 202, 100, 200);
P.Align := alCustom;
P.Caption := IntToStr(I * 100 + J);
P.ParentBackground := False;
P.Color := Random(clWhite);
P.Parent := ScrollBox1;
end;
end;
finally
ScrollBox1.VertScrollBar.Position := 0;
ScrollBox1.EnableAlign;
end;
end;
如何更好地解决这个问题? 使用
TControl
衍生工具来绕过对SetWindowPos
的API调用,而不是TPanel
(aTWinControl
)
如何最好地解决它?
使用虚拟方法,如
TDBControlGrid
does,只显示几个面板,同时给人留下很多面板的印象。请向质量中心提交错误报告。这也是搜索已知错误的地方。请向质量中心提交错误报告。这也是搜索信息的地方