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

后端 未结 4 1311
傲寒
傲寒 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");
    }
    

提交回复
热议问题