检查RichTextBox滚动条的拇指是否在滚动条的底部

本文关键字:滚动条 底部 是否 RichTextBox 检查 | 更新日期: 2023-09-27 18:11:48

我找到了这个链接WPF_Example,但它是用WPF编写的。我不是在WPF编程,我在Windows窗体中这样做,并没有真正的理由要嵌入一个WPF RichTextBox到我的应用程序只是为了获得我需要的答案。

有没有办法,使用WindowsForms(不是WPF),找出如果RichTextBox滚动条拇指在滚动条的底部?

这样做的目的是让我们的用户,谁正在查看聊天在RTF框,向上滚动,当文本添加,而不是向下滚动,如果他们是向上滚动。想想mIRC是如何处理聊天的;如果你在聊天框的底部,文本将自动滚动到视图中;如果你向上移动一行,文本就会被添加,而不需要滚动。

我需要复制它。我确实在这里找到了这个链接:List_ViewScroll,但我不确定它是否适用于这种情况。

任何帮助都将非常感激:)

使用这个类,我能够让它工作。非常感谢下面的人指出了这一点,并澄清了一些细节:

internal class Scrollinfo
{
    public const uint ObjidVscroll = 0xFFFFFFFB;
    [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
    private static extern int GetScrollBarInfo(IntPtr hWnd,
                                               uint idObject,
                                               ref Scrollbarinfo psbi);
    internal static bool CheckBottom(RichTextBox rtb)
    {

        var info = new Scrollbarinfo();
        info.CbSize = Marshal.SizeOf(info);
        var res = GetScrollBarInfo(rtb.Handle,
                                   ObjidVscroll,
                                   ref info);
        var isAtBottom = info.XyThumbBottom > (info.RcScrollBar.Bottom - info.RcScrollBar.Top - (info.DxyLineButton*2));
        return isAtBottom;
    }
}
public struct Scrollbarinfo
{
    public int CbSize; 
    public Rect RcScrollBar;
    public int DxyLineButton;
    public int XyThumbTop;
    public int XyThumbBottom;
    public int Reserved;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public int[] Rgstate;
}
public struct Rect
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}       

检查RichTextBox滚动条的拇指是否在滚动条的底部

所以,这个问题的答案不是非常复杂,但是相当冗长。关键是Win32 API函数GetScrollBarInfo,它很容易从c#中调用。您需要在表单中使用以下定义来调用…

[DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
private static extern int GetScrollBarInfo(IntPtr hWnd,
    uint idObject, ref SCROLLBARINFO psbi);
public struct SCROLLBARINFO {
    public int cbSize;
    public RECT rcScrollBar;
    public int dxyLineButton;
    public int xyThumbTop;
    public int xyThumbBottom;
    public int reserved;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public int[] rgstate;
}
public struct RECT {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}        

为了测试GetScrollBarInfo,考虑创建一个带有RichTextBox和一个按钮的表单。在按钮的点击事件中,进行以下调用(假设你的RichTextBox被命名为"richTextBox1")…

uint OBJID_VSCROLL = 0xFFFFFFFB;
SCROLLBARINFO info = new SCROLLBARINFO();
info.cbSize = Marshal.SizeOf(info);
int res = GetScrollBarInfo(richTextBox1.Handle, OBJID_VSCROLL, ref info);
bool isAtBottom = info.xyThumbBottom >
    (info.rcScrollBar.Bottom - info.rcScrollBar.Top - 20);

调用后,一个简单的公式可以确定滚动条的拇指是否在底部。从本质上讲, info.rcScrollBar。底部info.rcScrollBar。Top是屏幕上的位置,它们之间的差异将告诉您滚动条的大小,无论它在屏幕上的哪个位置。与此同时,信息。xyThumbBottom标记拇指按钮底部的位置。"20"基本上是对滚动条向下箭头大小的猜测。你看,拇指按钮的底部实际上永远不会一直到滚动条的底部(这就是差异给你的),所以你必须为向下按钮减去额外的量。考虑到按钮的大小会根据用户的配置而有所不同,这确实有些不稳定,但这应该足以让您开始。

我的朋友(专业程序员)给了我这个解决方案,它工作得很好(比几年前提供的解决方案要好):

var isAtBottom = rt.GetPositionFromCharIndex(rt.Text.Length)。Y & lt;rt.Height;