-
Aug 14th, 2018, 11:15 AM
#1
Thread Starter
New Member
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
-
Aug 14th, 2018, 12:54 PM
#2
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
-
Aug 14th, 2018, 01:02 PM
#3
Thread Starter
New Member
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.
-
Aug 14th, 2018, 01:13 PM
#4
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?
-
Aug 14th, 2018, 01:16 PM
#5
Thread Starter
New Member
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.
-
Aug 14th, 2018, 01:44 PM
#6
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...
-
Aug 14th, 2018, 01:54 PM
#7
Thread Starter
New Member
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.
-
Aug 14th, 2018, 02:04 PM
#8
Thread Starter
New Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|