如何检测滚动条是否在底部?

9

检测一个TScrollBox的垂直滚动条是否在最顶部非常简单:

IsScrollBarAtTop := ScrollBox1.VertScrollBar.Position = 0;

我该如何检测一个 TScrollBox 的垂直滚动条是否滚动到了底部?
请参考以下图片: enter image description here 如果您需要翻到底,请查看下面的图片:enter image description here

一个有点“出奇制胜”的想法……由于滚动条是表示您在滚动的内容中所处位置的抽象表示,也许更好的方法是查看底层视图中的位置。例如,对于文本编辑器/查看器:您是否在文件的最后一行? - Disillusioned
3个回答

13

您可以通过API获取滚动条信息,并确定其是否在底部。

function IsScrollBarAtBottom(Box: TScrollBox): Boolean;
var
  Info: TScrollInfo;
begin
  Info.cbSize := SizeOf(Info);
  Info.fMask := SIF_POS or SIF_RANGE or SIF_PAGE;
  Win32Check(GetScrollInfo(Box.Handle, SB_VERT, Info));
  Result := Info.nPos >=  Info.nMax - Info.nMin - Info.nPage;
end;

1
这本书的标题也可以是:“Delphi的聪明WinAPI解决方案”。 - user1580348
2
@user Delphi在这里并不是很相关。这是一个Win32控件和Win32答案。代码可以用任何语言编写。VCL是Win32的一种松散封装,使得这种事情变得容易。许多Delphi程序员害怕其他语言,不愿阅读任何其他语言编写的代码。这是一个巨大的弱点。不要害怕。学习足够的C++以能够阅读C++ Win32示例代码,并编写简单的C++程序,您将可以访问更有价值的信息。 - David Heffernan
要完成此操作,要知道滚动条是否在顶部,请使用 IsScrollBarAtTop := Info.nPos = 0; - user30478

10

来自Vcl.Forms.TControlScrollBar.Range

Range 表示关联控件客户区域的虚拟大小(以像素为单位)。例如,如果一个窗体水平滚动条的 Range 设置为 500,而该窗体的宽度为 200,则滚动条的位置可以从 0 到 300 变化。

IsScrollBarAtBottom :=  ScrollBox1.VertScrollBar.Position =
  (ScrollBox1.VertScrollBar.Range - ScrollBox1.ClientHeight);
如果区域小于滚动框的高度,则滚动条不可见。

很想知道是否有人可以确认这个是否有效。它在概念上与WinAPI解决方案相同,但更简单,没有挖掘洋葱层。 - Disillusioned
1
盒子的高度或客户端高度与可滚动范围之间没有直接对应关系。这将取决于按钮的厚度/高度,是否存在水平条等。不建议使用... - Sertac Akyuz
2
@SertacAkyuz,刚试了一下有和没有水平线,都可以工作。 - LU RD
1
@LURD - 你说得对。我有机会查看了TControlScrollBar的代码,它考虑了ControlSize中的按钮大小等因素。+1 - Sertac Akyuz

0

重要的值是内容的位置... ScrollBox.ViewportPosition。我找了一段时间,但在任何讨论中都没有提到,所以我在这里声明一下。(Delphi 10.2,FMX)


你能否添加一个文档链接以及一个代码片段,展示如何使用你的建议来回答问题,就像其他答案中所做的那样? - loonatick
您的回答可以通过添加更多的支持信息来改善。请点击[编辑]以添加进一步的细节,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心找到更多关于如何撰写好答案的信息。 - loonatick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接