How to detect if a scrollbar is or is not at the end of a richtextbox (vb.net)

后端 未结 4 1301
傲寒
傲寒 2020-12-17 06:02

my question is as is:How to detect if a scrollbar is at or not at the end of a richtextbox?

edit: when I say at the end I mean completely scrolled to the bottom, no

相关标签:
4条回答
  • 2020-12-17 06:22

    I used this code to get the current and maximum positions correctly:

        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;
            }
        }
    

    It's tedious to get the "correct" maximum value. You have to substract the nPage (large change) value of the max value GetScrollRange returns, and then you can compare it with the HScrollPosition property correctly, like:

    if (_rtb.VScrollPosition == _rtb.VScrollPositionMax)
    {
        Debug.WriteLine("Scroll is at the bottom most edge");
    }
    
    0 讨论(0)
  • 2020-12-17 06:23

    One method is to use the GetScrollPos function. Here's kind of a long winded example of it using VB.NET.

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

    0 讨论(0)
  • 2020-12-17 06:32
            if (richTextBox1.Size.Width - richTextBox1.ClientSize.Width > 10) 
    

    Sorry, you'll have to convert that to VB.NET yourself. Shouldn't be too hard :)

    0 讨论(0)
  • 2020-12-17 06:40

    Check out the GetScrollRange and GetScrollPos 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
    

    Notes:

    To determine if the scrollbar is visible, call GetWindowLong and check for WS_VSCROLL

    To determine the max value the slider can get to, call GetScrollInfo; I think the maximum value is

    scrollMax - largeChange + 1
    
    0 讨论(0)
提交回复
热议问题