【问题标题】:How to detect if a scrollbar is or is not at the end of a richtextbox (vb.net)如何检测滚动条是否位于富文本框的末尾(vb.net)
【发布时间】:2010-10-13 23:58:22
【问题描述】:

我的问题是:如何检测滚动条是否位于富文本框的末尾?

编辑:当我说最后我的意思是完全滚动到底部,而不是其他任何地方。

【问题讨论】:

    标签: .net vb.net scroll richtextbox scrollbar


    【解决方案1】:

    查看GetScrollRangeGetScrollPos API...

    Private Const SBS_HORZ = 0
    Private Const SBS_VERT = 1
    
    <DllImport("user32.dll")> _
    Public Function GetScrollRange(ByVal hWnd As IntPtr, ByVal nBar As Integer, _
                                   ByRef lpMinPos As Integer, _
                                   ByRef lpMaxPos As Integer) As Boolean
    End Function
    
    <DllImport("user32.dll")> _
    Public Function GetScrollPos(ByVal hWnd As Integer, _
                                 ByVal nBar As Integer) As Integer
    End Function
    
    // ...
    
    Dim scrollMin as Integer = 0
    Dim scrollMax as Integer = 0
    
    If(GetScrollRange(rtb.Handle, SBS_VERT, scrollMin, scrollMax) Then
       Dim pos as Integer = GetScrollPos(rtb.Handle, SBS_VERT)
    
       // Detect if they're at the bottom
    EndIf
    

    注意事项:

    要确定滚动条是否可见,请调用GetWindowLong 并检查WS_VSCROLL

    要确定滑块可以达到的最大值,请调用GetScrollInfo;我认为最大值是

    scrollMax - largeChange + 1
    

    【讨论】:

    • ok 效果很好,但还有两件事:我如何知道滚动条是否可见,以及如何获取滚动条的最后可能位置?
    • 我可以调用 getScrollInfo 但我只是不知道如何构建返回最后一个位置的函数。你能帮我吗?
    【解决方案2】:

    我使用此代码正确获取当前和最大位置:

        const int SB_HORZ          = 0x0000;
        const int SB_VERT          = 0x0001;
        const int WM_HSCROLL       = 0x0114;
        const int WM_VSCROLL       = 0x0115;
        const int SB_THUMBPOSITION = 4;
    
        private enum ScrollInfoMask : uint
        {
            SIF_RANGE           = 0x1,
            SIF_PAGE            = 0x2,
            SIF_POS             = 0x4,
            SIF_DISABLENOSCROLL = 0x8,
            SIF_TRACKPOS        = 0x10,
            SIF_ALL             = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
        }
    
        [StructLayout(LayoutKind.Sequential)]
        struct SCROLLINFO
        {
            public uint cbSize;
            public uint fMask;
            public int  nMin;
            public int  nMax;
            public uint nPage;
            public int  nPos;
            public int  nTrackPos;
        }
    
        public int HScrollPosition
        {
            get
            {
                return GetScrollPos(Handle, SB_HORZ);
            }
            set
            {
                SetScrollPos((IntPtr)Handle, SB_HORZ, value, true);
                PostMessageA((IntPtr)Handle, WM_HSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0);
            }
        }
    
        public int VScrollPosition
        {
            get
            {
                return GetScrollPos(Handle, SB_VERT);
            }
            set
            {
                SetScrollPos((IntPtr)Handle, SB_VERT, value, true);
                PostMessageA((IntPtr)Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0);
            }
        }
    
        public int HScrollPositionMax
        {
            get
            {
                SCROLLINFO scrollInfo = new SCROLLINFO();
                scrollInfo.fMask = (uint)ScrollInfoMask.SIF_ALL;
                scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo);
                GetScrollInfo(Handle, SB_HORZ, ref scrollInfo);
    
                return scrollInfo.nMax - (int)scrollInfo.nPage;
            }
        }
    
        public int VScrollPositionMax
        {
            get
            {
                SCROLLINFO scrollInfo = new SCROLLINFO();
                scrollInfo.fMask = (uint)ScrollInfoMask.SIF_ALL;
                scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo);
                GetScrollInfo(Handle, SB_VERT, ref scrollInfo);
    
                return scrollInfo.nMax - (int)scrollInfo.nPage;
            }
        }
    

    获得“正确”的最大值很繁琐。您必须减去GetScrollRange返回的最大值的nPage(大变化)值,然后您可以将其与HScrollPosition属性正确比较,例如:

    if (_rtb.VScrollPosition == _rtb.VScrollPositionMax)
    {
        Debug.WriteLine("Scroll is at the bottom most edge");
    }
    

    【讨论】:

    • 我注意到,当 RichTextBox 的“显示”区域高度不是字体高度的倍数时,有时滚动位置(例如 nPos)并不完全等于最大值(例如. nMax - nPage ),因为在最后实际文本行下方有一个“部分行”文本,但是滚动位置被量化到最近的行,使得 nMax 比预期的高一点。我想人们也可以从 nMax 中减去一行文本的高度减去一个 - 这样,“足够接近”的滚动位置算作“最大”。可能会尝试一下;可能会报告。
    【解决方案3】:
            if (richTextBox1.Size.Width - richTextBox1.ClientSize.Width > 10) 
    

    抱歉,您必须自己将其转换为 VB.NET。应该不会太难:)

    【讨论】:

      【解决方案4】:

      一种方法是使用 GetScrollPos 函数。这是一个使用 VB.NET 的冗长示例。

      http://www.codeproject.com/KB/vb/VbNetScrolling.aspx?print=true

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多