Как определить, находится ли полоса прокрутки в конце RichTextBox или нет (vb.net)

мой вопрос таков: как определить, находится ли полоса прокрутки в конце RichTextBox или нет?

редактировать: когда я говорю в конце, я имею в виду полностью прокручен до конца, а не где-либо еще.


person fbernier    schedule 18.03.2009    source источник


Ответы (4)


Ознакомьтесь с GetScrollRange и 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

Примечания:

Чтобы определить, видна ли полоса прокрутки, вызовите GetWindowLong и проверьте наличие WS_VSCROLL

Чтобы определить максимальное значение, которое может получить ползунок, вызовите GetScrollInfo; Я думаю, что максимальное значение

scrollMax - largeChange + 1
person Daniel LeCheminant    schedule 18.03.2009
comment
хорошо работает, но есть еще две вещи: как я могу узнать, видна ли полоса прокрутки, и как я могу получить последнюю возможную позицию полосы прокрутки? - person fbernier; 18.03.2009
comment
Я могу сделать вызов getScrollInfo, но я просто не знаю, как построить функцию, которая вернет последнюю позицию. не могли бы вы помочь мне с этим? - person fbernier; 18.03.2009

Я использовал этот код, чтобы правильно получить текущую и максимальную позиции:

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

Утомительно получить «правильное» максимальное значение. Вы должны вычесть значение nPage (большое изменение) из максимального значения, которое возвращает GetScrollRange, а затем вы можете правильно сравнить его со свойством HScrollPosition, например:

if (_rtb.VScrollPosition == _rtb.VScrollPositionMax)
{
    Debug.WriteLine("Scroll is at the bottom most edge");
}
person Ray    schedule 04.02.2013
comment
Я заметил, что когда RichTextBox имеет высоту области отображения, которая не кратна высоте шрифта, иногда положение прокрутки (например, nPos) не совсем равно максимальному (например, nMax - nPage), потому что существует часть строки текста ниже последней фактической строки текста, но положение прокрутки квантуется до ближайшей строки, что делает nMax немного выше, чем ожидалось. Я полагаю, что можно также вычесть из nMax высоту строки текста за вычетом единицы - таким образом, положение прокрутки, которое достаточно близко, считается максимальным. Вероятно, попробую; может отчитаться. - person bernz; 20.07.2017

        if (richTextBox1.Size.Width - richTextBox1.ClientSize.Width > 10) 

Извините, вам придется преобразовать это в VB.NET самостоятельно. Не должно быть слишком сложно :)

person Orwellophile    schedule 13.12.2011

Один из способов — использовать функцию GetScrollPos. Вот довольно длинный пример использования VB.NET.

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

person BobbyShaftoe    schedule 18.03.2009