Solved

Scroll Loop For RichTextBox

Posted on 2007-12-05
10
468 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:H-SC
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
arif_eqbal,

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

Expert Comment

by:taverny
Comment Utility
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

763 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

6 Experts available now in Live!

Get 1:1 Help Now