views:

1341

answers:

2

I have a RichTextBox and I need to find the position of the vertical scroll bar.

Is there any way to do this without Pinvoke? If not, what is a way to do this WITH Pinvoke?

I need to return an integer value.

Thanks for the help!

+1  A: 

I don't know any way to do this without PInvoke. You can use PInvoke to call GetScrollPos.

Here's how you can try it.

Step 1: Create a custom RichTextBox control by extending a standard RichTextBox.

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Windows.Forms

Namespace WindowsFormsApplication1

    Public Class MyRichTextBox
        Inherits RichTextBox
        <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
        Public Shared Function GetScrollPos(ByVal hWnd As IntPtr, ByVal nBar As Integer) As Integer
        End Function

        <DllImport("user32.dll")> _
        Private Shared Function SetScrollPos(ByVal hWnd As IntPtr, ByVal nBar As Integer, ByVal nPos As Integer, ByVal bRedraw As Boolean) As Integer
        End Function

        Private Const SB_HORZ As Integer = &H0
        Private Const SB_VERT As Integer = &H1

        ''' <summary>
        ''' Gets and Sets the Horizontal Scroll position of the control.
        ''' </summary>
        Public Property HScrollPos() As Integer
            Get
                Return GetScrollPos(DirectCast(Me.Handle, IntPtr), SB_HORZ)
            End Get
            Set(ByVal value As Integer)
                SetScrollPos(DirectCast(Me.Handle, IntPtr), SB_HORZ, value, True)
            End Set
        End Property

        ''' <summary>
        ''' Gets and Sets the Vertical Scroll position of the control.
        ''' </summary>
        Public Property VScrollPos() As Integer
            Get
                Return GetScrollPos(DirectCast(Me.Handle, IntPtr), SB_VERT)
            End Get
            Set(ByVal value As Integer)
                SetScrollPos(DirectCast(Me.Handle, IntPtr), SB_VERT, value, True)
            End Set
        End Property
    End Class
End Namespace

This will add two properties to a standard RichTextBox: HScrollPos and VScrollPos. These properties will allow you go get and set the horizontal and vertical scrollbar position in your control.

Step 2: Create a test form and try out your control.

Create a Winform in the same project as your custom control. Drop the custom control in the test form and add a button on the form. In the form's Click event, add the following code to view your custom control's vertical scroll position.

Console.WriteLine(myRichTextBox1.VScrollPos)

A few things to watch for:

  1. If your control is not currently displaying a vertical scrollbar, the call to HScrollPos will crash your program. There are a few obviously ways around this (check that the scrollbar is being displayed before checking the property, or making the vertical scrollbar always visible, etc.).

  2. Depending on how the control (and possibly form) is sized (not to mention changes in the text contents of the control), setting the VScrollPos can crash your program or not restore it to the position it was in when the VScrollPos value was saved.

  3. I've never used this code. I thought your question was interesting and did a little bit of research to come up with my answer.

Jay Riggs
Works great!!! Thanks so much! I wonder why they didn't create a wrapper for that method, it would have made sense lol. I wish I could upvote more than once!
Cyclone
Good, I'm glad it helped.
Jay Riggs
A: 

(I realize this is months later, but I'm hopeful :)

Jay,

You're my hero - almost. I've been trying messing with the richtext scrollbars for days, only to realize that they're broken. Your code allows me to read the scrollbar !!!!

However, when I set the position, the scrollbar moves, but not the text in the text box! If I try to touch anything, it the scrollbar position zips back to the top. The workaround right now is to immediately click on the scroller as soon as it is up. I've tried refresh and update functions, they move me to the top. Any ideas, anyone? Right now I'm thinking about some sort of raise event kludge to "click" on the scroller.

Thanks, Chris

Chris
You ought to post this as a comment on Jay's answer instead of as an answer to my question
Cyclone