Results 1 to 8 of 8

Thread: Scroll a richtextbox to a previous position without undoing current selection

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2017
    Posts
    7

    Scroll a richtextbox to a previous position without undoing current selection

    I have a richtextbox in which I sometimes programmatically select a large chunk of text extending down past the bottom of the screen. Selecting it normally causes the screen to reposition to the end of the selection. I want the screen to stay right where it was. Using normal visual basic commands, I can't reposition to where I started without losing the selection.
    I thought I had a solution using the GetScrollPos and SetScrollPos APIs, but when I installed my program on another computer, it didn't work (no errors, just didn't do anything). Microsoft says not to use them, but to use GetScrollInfo instead.
    Oddly, there is virtually nothing on the internet for VB.Net and GetScrollInfo other than a few Microsoft documents that don't give any examples of how to actually implement it and some old pre-VB6 code that doesn't work for me. What follows is a kind of mishmash of different snippets, so I'm not sure it all makes sense together, and it doesn't work, but it's what I've got for now.

    Code:
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
      (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
     
    Private Const EM_GETTHUMB = &HBE
    Private Const SB_THUMBPOSITION = &H4
    Private Const WM_VSCROLL = &H115
    Private Const SB_VERT As Integer = &H1
    Private Const SIF_RANGE As Integer = &H1
    Private Const SIF_PAGE As Integer = &H2
    Private Const SIF_POS As Integer = &H4
     
    Private Declare Function GetScrollInfo Lib "user32" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByRef si As SCROLLINFO) As Long
    Private Declare Function SetScrollInfo Lib "user32" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByRef si As SCROLLINFO, ByVal bRedraw As Boolean) As Long
     
    <StructLayout(LayoutKind.Sequential)>
    Private Structure SCROLLINFO
        Public cbSize As Integer
        Public fMask As Integer
        Public nMin As Integer
        Public nMax As Integer
        Public nPage As Integer
        Public nPos As Integer
        Public nTrackPos As Integer
    End Structure
     
    Public Function GetVerticalScrollPos(rtb As RichTextBox) As Long
        Dim si As New SCROLLINFO
        si.cbSize = Marshal.SizeOf(GetType(SCROLLINFO))
        si.fMask = SIF_RANGE Or SIF_PAGE Or SIF_POS
        GetScrollInfo(rtb.Handle, SB_VERT, si)
        Return si.nPos
    End Function
     
    Public Sub SetVerticalScrollPos(rtb As RichTextBox, Position As Long)
        Dim si As New SCROLLINFO With {
            .cbSize = Marshal.SizeOf(GetType(SCROLLINFO)),
            .fMask = SIF_RANGE Or SIF_PAGE Or SIF_POS
        }
        GetScrollInfo(rtb.Handle, SB_VERT, si)
        si.nPos = Position
        SetScrollInfo(rtb.Handle, SB_VERT, si, True)
    End Sub

  2. #2
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Scroll a richtextbox to a previous position without undoing current selection

    Maybe something like this
    Code:
    Public Class RichTBExample
        Dim LineStart As Integer = 0
        Private Sub RichTextBox1_SelectionChanged(sender As Object, e As EventArgs) Handles RichTextBox1.SelectionChanged
            LineStart = RichTextBox1.SelectionStart
        End Sub
    
        Private Sub RichTextBox1_MouseUp(sender As Object, e As EventArgs) Handles RichTextBox1.MouseUp
            RichTextBox1.Copy() 'copy selection to cb?
            RichTextBox1.SelectionLength = 0 'clear selection
            RichTextBox1.SelectionStart = LineStart 'return 'focus' back to startselection
        End Sub
    End Class

  3. #3

    Thread Starter
    New Member
    Join Date
    Oct 2017
    Posts
    7

    Re: Scroll a richtextbox to a previous position without undoing current selection

    No, the problem is that I don't want to deselect it. I want the user to be able to scroll, if he so wishes, to see exactly what was selected and copied before choosing whether to paste it into another application. If I go back to selectionstart, with length=0, then he doesn't know what, if anything, was copied. How much I select is somewhat context driven, so, although it should usually be exactly what he wants, I don't want to leave the user in the dark.

  4. #4
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Scroll a richtextbox to a previous position without undoing current selection

    So if I am understanding you you want to handle the selection in code, and the user will not actually drag to select?

  5. #5

    Thread Starter
    New Member
    Join Date
    Oct 2017
    Posts
    7

    Re: Scroll a richtextbox to a previous position without undoing current selection

    That's correct. If the user has selected anything, it will copy exactly what he chose. If nothing is selected, then hitting a copy button will automatically select one "chapter" and copy it to the clipboard.

  6. #6
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Scroll a richtextbox to a previous position without undoing current selection

    What if you created a RTB object in code and set it to the visible RTB and made your selection from that which user would not even see, or do you prefer that the user can see the selected text, just from the begining of the selection...

  7. #7

    Thread Starter
    New Member
    Join Date
    Oct 2017
    Posts
    7

    Re: Scroll a richtextbox to a previous position without undoing current selection

    My preference is that nothing moves on screen, but text is selected so that the user can see that something was indeed copied and can verify how much was copied. At times, when the visible text overlaps the dividing point between two chapters, if the user has clicked within the chapter he wants, it will select that chapter. But if he has just scrolled to this page, the program will assume he wants whatever text is at the top of the page. Having the text become visibly selected will let him know it's not what he wanted, and he can click in the correct section, and with a single button press copy that whole chapter. It's faster and more convenient than clicking at the start, scrolling to the end, clicking and copying, and then scrolling back to the beginning where he was reading.

  8. #8

    Thread Starter
    New Member
    Join Date
    Oct 2017
    Posts
    7

    Re: Scroll a richtextbox to a previous position without undoing current selection

    I think this is the code that worked on my programming laptop, but it failed when I installed it on a hybrid Windows tablet. Maybe it would be easier to figure out what went wrong here:

    Code:
    Code:
    'In a module
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
      (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    
    Private Const EM_GETTHUMB = &HBE
    Private Const SB_THUMBPOSITION = &H4
    Private Const WM_VSCROLL = &H115
    
    Public Function GetVerticalScrollPos(rtb As RichTextBox) As Long
      GetVerticalScrollPos = SendMessage(rtb.handle, EM_GETTHUMB, 0&, 0&)
    End Function
    
    Public Sub SetVerticalScrollPos(rtb As RichTextBox, Position As Long)
      SendMessage(rtb.handle, WM_VSCROLL, SB_THUMBPOSITION + &H10000 * Position, Nothing)
    End Sub
    
    'In your subroutine
    Dim Vertical_Pos as Long
    
    Vertical_Pos = GetVerticalScrollPos(rtb)
    rtb.text = "blah blah blah"
    Call SetVerticalScrollPos(rtb, Vertical_Pos)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width