Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Scroll Loop For RichTextBox

Posted on 2007-12-05
10
Medium Priority
?
497 Views
Last Modified: 2012-06-21
I have a richtextbox on a form.  I need for all of the text inside the box to scroll upwards/vertically at a readable pace end to end in a continuous loop.  Any ideas would be greatly appreciated.
0
Comment
Question by:H-SC
  • 6
  • 3
10 Comments
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 20418640
Hi
I have tried to create a sample for you, see the Code Snippet for the code.
However there are a few clarifications
what do you exactly mean by "end to end in a continuous loop"
What i have done is when I reach the Bottom of Textbox I again start from the top.
You could as well start scrolling backwards till you reach the Top and then repeat the cycle.
Another important point, I assume that user would not be Typing in any text while we are scrolling.
This code is a very simple representation of your problem, I assume I have full control of the Caret and am using to reposition the caret so that I can scroll to that position. So this code might not work if some other code changes the caret position. Ideally the RichTextBox should have ReadOnly=True
Also, I am scrolling Line By Line, so typically you should have these 2 propertie set for the RichTextBox
1.  ScrollBars = Horizontal
2.  WordWrap = False
In case you do not have proper Line Breaks in the text in the code, again this code fails.
So in case this solution doesn't work we would be left with the other rather avoidable solution and that is using Win APIs. Typically we can use SendMessage API to send a VSCROLL Message to the richTextBox so that it does vertical scrolling.
Dim ScrollTimer As New Timer
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ScrollTimer.Interval = 1000
        AddHandler ScrollTimer.Tick, AddressOf ScrollTimer_Tick
End Sub
 
    Private Sub ScrollTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim CurrLine As Integer = RTB.GetLineFromCharIndex(RTB.SelectionStart)
        CurrLine += 1
 
        If (CurrLine < RTB.Lines.Length) Then
            RTB.Select(RTB.GetFirstCharIndexFromLine(CurrLine), 0)
            RTB.ScrollToCaret()
        Else
            RTB.Select(RTB.GetFirstCharIndexFromLine(0), 0)
            RTB.ScrollToCaret()
        End If
    End Sub
 
     Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        ScrollTimer.Enabled = True
    End Sub

Open in new window

0
 
LVL 1

Author Comment

by:H-SC
ID: 20419532
arif_eqbal,

This is great!  
The end to end means when the scrolling reaches the last line of text in the box to start the first line at the bottom and scroll up almost like movie credits just in a continuious loop.

there will be no user input for this particular textbox

The only thing that I see when I paste the text in is that it scrolls correctly until it reaches the end and then it stays on the last line of text and scrolls up and down for about 30 sec. and then starts back at the top.  This may be the line break item that you mentioned that would cause the code to fail.

Is the API idea very complex?
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 20425469
Ok this code was just a trial thing
now we can polish it, if this code works lets avoid the API thing as it will be an unmanaged code.
The API would use the Scroll Bars while in our case there isn't any vertical scrollbar at all.
anyway, I will try to modify this code so that the single row up/Down scrolling when it reaches the end is removed. Also i will make it scroll alternately in either direction.

I will also try and make the API stuff, it will not be as difficult, Just that I would need to search the net or API library for the particular constant value needed to move the scrollbar. And that would be probably only 2-3 lines of code.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 19

Expert Comment

by:arif_eqbal
ID: 20425917
Hi there,
I have modified the code I posted earlier, which I am putting here see the Attached Snippet.
also i have tried the API stuff. However, there's one issue with either of them, in API its rather fragile how we detect if we have reached the end or top. I will post this API code separately, you can test both and decide which you want.
For our current solution, the problem you had was that when we reached the bottom it would sort of Flicker Up and Down for a few seconds. That was happening because we were trying to scroll down till the last line ignoring the fact the based on the height of the RichTextBox the last line would reach when say the 10th line is at the top. For eg. assume your RichTextBox has 50 Lines of text, but at a time it displays only 10 lines, rest 40 are not visible you need to scroll down to see them. So we actually need to scroll ony upto the 41st line then 41-50 lines would be visible.
I have updated the code to handle that.
now you have to do this though, Find out how many lines are visible at a time in your RichTextBox and change the variable "VISIBLELINES" to that value currently I have it at 7 because thats the value based on my RichTextBox size.
Please check this code, (I will post the API one in some time)

    Dim ScrollTimer As New Timer
    Dim VISIBLELINES As Integer = 7 'No of Lines that are visible at a time, this would change based on the height of RichTextBox, its Font and FontSize
    Dim MOVEDOWN As Boolean = True
    
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        ScrollTimer.Interval = 1000 'Scroll Up/Down every 1 Sec
        AddHandler ScrollTimer.Tick, AddressOf ScrollTimer_Tick
 
    End Sub
 
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        ScrollTimer.Enabled = True
    End Sub
 
    Private Sub ScrollTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim CurrLine As Integer = RTB.GetLineFromCharIndex(RTB.SelectionStart)
        If (MOVEDOWN) Then
            ScrollDown(CurrLine)
        Else
            ScrollUp(CurrLine)
        End If
    End Sub
 
    Private Sub ScrollDown(ByVal CurrLine As Integer)
        CurrLine += 1
        If (CurrLine <= RTB.Lines.Length - VISIBLELINES) Then
            RTB.Select(RTB.GetFirstCharIndexFromLine(CurrLine), 0)
            RTB.ScrollToCaret()
        Else
            MOVEDOWN = False 'Can call ScrollUp immediately from here, but lets wait an extra second when we reach the Bottom
        End If
    End Sub
 
    Private Sub ScrollUp(ByVal CurrLine As Integer)
        CurrLine -= 1
        If (CurrLine >= 0) Then
            RTB.Select(RTB.GetFirstCharIndexFromLine(CurrLine), 0)
            RTB.ScrollToCaret()
        Else
            MOVEDOWN = True 'Can call ScrollDown immediately from here, but lets wait an extra second when we reach the Top
        End If
    End Sub

Open in new window

0
 
LVL 19

Accepted Solution

by:
arif_eqbal earned 2000 total points
ID: 20426407
OK
So here's the same thing using Win APIs
use this in case you face issues with the previous one

    Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
 
 Const WM_VSCROLL As Int32 = &H115
    Const SB_LINEDOWN As Int32 = 1
    Const SB_LINEUP As Int32 = 0
 
 Dim SCROLLING As Boolean = True
 Dim MOVEDOWN As Boolean = True
 Dim APIScrollTimer As New Timer
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler RTB.VScroll, AddressOf RTB_Scrolling 'RTB is my RichTextBox
        APIScrollTimer.Interval = 1000 'Scroll Up/Down every 1 Sec
        AddHandler APIScrollTimer.Tick, AddressOf APIScrollTimer_Tick
    End Sub
 
    Private Sub APIScrollTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'If currently We are not scrolling it means we are either at Top or at Bottom
        'So reverse the MOVEDOWN value
        If Not SCROLLING Then MOVEDOWN = Not MOVEDOWN
        'Now assume that this call to Scroll is worthless, i.e. we are already at Bottom or Top so no scrolling would occur
        'So set the SCROLLING to False, However if we Do Scroll actually, then the event handler for scrolling would Set this flag anyway
        SCROLLING = False
        If (MOVEDOWN) Then
            ScrollDown()
        Else
            ScrollUp()
        End If
    End Sub
 
    Private Sub ScrollUp()
        SendMessage(RTB.Handle, WM_VSCROLL, SB_LINEUP, 0)
    End Sub
 
    Private Sub ScrollDown()
        SendMessage(RTB.Handle, WM_VSCROLL, SB_LINEDOWN, 0)
    End Sub
 
    Private Sub RTB_Scrolling(ByVal sender As Object, ByVal e As EventArgs)
        SCROLLING = True 'We are still Scrolling either Down or UP
    End Sub

Open in new window

0
 
LVL 1

Author Comment

by:H-SC
ID: 20427465
arif_eqbal,

the api version worked great...  when the scroll gets to the bottom it starts reversing and scrolls back up to the top.  Is there any way to get it to move to the top or first line when it reaches the bottom and start again
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 20439664
Oh Sure Yes we can do that.
I thought you wanted it to move circular thats why I did it that way.
Let me just modify and post back.
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 20439854
OK So find attached the code,
You need to Declare the Constant
and change the Code in ScrollUP function to use this Constant instead of the old one
Const SB_TOP As Int32 = 6
 
 Private Sub ScrollUp()
        SendMessage(RTB.Handle, WM_VSCROLL, SB_TOP, 0)
    End Sub

Open in new window

0
 
LVL 1

Author Comment

by:H-SC
ID: 20445016
arif_eqbal,

thats perfect!  Many thanks for your help on this.
0
 

Expert Comment

by:taverny
ID: 22011217
Hi Arif_eqbal,

I am trying to do the same thing as you did here but I would like to feed the text from a database. basically I would like to have a website that shows our rush job number on a screen ( like an aiport display)  those jobs would be pulled real time from an access databse.
let me know if you would know how to do this and I will open a question with some points.
Thanks
Dave
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

971 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question