Solved

Scroll Loop For RichTextBox

Posted on 2007-12-05
10
474 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
 
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 500 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …

911 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now