Link to home
Start Free TrialLog in
Avatar of Stuart Landreth
Stuart LandrethFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Smooth Scrolling Text

I am trying to create a right-to-left text scroller similar to the news tickers found on TV channels like Sky News, etc.

The scrolling effect needs to be as smooth as possible (i.e. as close to broadcast quality as possible). It is feasable that a lot of CPU power can be used to process the scrolling if needbe.

I have investigated various examples using Hires (multimedia?) timers which seem to be the most sucessful, but the problem i have is that the text flickers and the scrolling is not smooth, especially ones which make use of moving labels.

Can somebody suggest some code which will render the scrolling effect with as little flicker as possible.

The text will be in Arial font, at least size 48
Avatar of Stuart Landreth
Stuart Landreth
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

Supplemental to above, I already have code for a timer, which is firing (e.g.) every 20 milliseconds, so all I need is the text rendering code. Cheers.
Flickering may not neccessarily depend on the speed of the computer. It also depends on how you have written your code. You can have your text in a Label control with autosize property set to true and then can reduce the .Left property to simulate a text-scrolling. But if you do this, then you are sure to get flickering problems. Before I remember using the BitBlt API to draw many images on the form. I used to get lots of flickering problem. I solved this problem with using a time tested solution by using BitBlt on a buffer (Maybe a picturebox control). All the image copying and text coloring would be done to this buffer and the changes would not be seen due to it being invisible. Once the processing is over, I would simple copy the buffer to the form and voila, the flickering is gone. Maybe you could try this method.

Hope this answers your question :)
I managed to find this on an example

   Dim hRgn&
         
          '// print the text to the user control
          '// using paths
          With UserControl
            'open a path bracket
            BeginPath .hdc
            'draw the text
            TextOut .hdc, m_x&, 0, m_text$, Len(m_text$)
            'close the path bracket
            EndPath .hdc
            'convert the path to a region
            hRgn = PathToRegion(.hdc)
            'set the Window-region
            SetWindowRgn .hWnd, hRgn, True
            'destroy our region
            DeleteObject hRgn
         End With


which seems to use paths and regions, but still flickers a bit.

Can you give me an example of using BitBlt API as I am not not familiar with it. Thanks,.
Please give me some time, I'll work on it.
Ok I got something that works without flickering, but may not be like the cool one's that you see on tv. One a new executable project, add a timer (Timer1) and a picture box control (Picture1). Then set the following properties.

Form (Form1):
ScaleMode: 3 - Pixel

Timer (Timer1):
Interval: 50

Picture control (Picture1):
ScaleMode: 3 - Pixel
Height: 30
AutoRedraw: True
Visible: False
Appearance: 0 - Flat
BorderStyle: 0 - None




Finally copy and paste the following code...
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Sub Form_Load()
'this sizes the picture box control according to our need
setPicSize "President George W. Bush has been re-elected in the USA elections"
End Sub

Private Sub setPicSize(strText As String)
'resize the control according to the size of the text
Picture1.Width = Picture1.TextWidth(strText) + 3
'set the starting point of the text to be printed
Picture1.CurrentX = 1
Picture1.CurrentY = (Picture1.Height - Picture1.TextHeight("*")) * 0.5
Picture1.Print strText
End Sub

Private Sub Timer1_Timer()
'variable to see how much from the left should we print
Static pX As Integer

'this copies the image from one place to another
Me.Cls
BitBlt Me.hDC, 0, Me.ScaleHeight - 30, Me.ScaleWidth, 30, Picture1.hDC, pX, 0, vbSrcCopy
pX = pX + 1
If pX > Picture1.Width Then pX = 10
End Sub
Oops, just found a mistake. In the second last line, the statement should be 'If pX > Picture1.Width Then pX = 0'

I would suggest you look up tutorials on BitBlt. There is a lot that you can do with it. :)
I appreciate the effort you have gone to with this code, but in-line with the size i need the scroller to be...

if you change the font in the picturebox to 48, perhaps white on black background and change

BitBlt Me.hDC, 0, Me.ScaleHeight - 30, Me.ScaleWidth, 30, Picture1.hDC, pX, 0, vbSrcCopy
to
BitBlt Me.hDC, 0, Me.ScaleHeight - 100, Me.ScaleWidth, 100,Picture1.hDC, pX, 0, vbSrcCopy

it flickers like mad!

any suggestions?
Aha - set the Form's Auto-Redraw to True and it seems to stop the flicker!!!
Firstly, in order to get white text on black background, just change the foreground property of the picture box to 'white' and 'backcolor' to 'black'

I changed the font property of the picture control to 'Arial (Bold), size 48'. I changed the height to 74

Finally, the flickering is not because of the BitBlt API. But maybe because of the Me.Cls statement. In order to correct this, I have removed the Me.Cls line and modified the line which resizes the picture control.


NEW CODE:




Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Sub Form_Load()
'this sizes the picture box control according to our need
setPicSize "President George W. Bush has been re-elected in the USA elections"
End Sub

Private Sub setPicSize(strText As String)
'resize the control according to the size of the text
Picture1.Width = Picture1.TextWidth(strText) + Me.ScaleWidth
'set the starting point of the text to be printed
Picture1.CurrentX = 1
Picture1.CurrentY = (Picture1.Height - Picture1.TextHeight("*")) * 0.5
Picture1.Print strText
End Sub

Private Sub Timer1_Timer()
'variable to see how much from the left should we print
Static pX As Integer

'this copies the image from one place to another
BitBlt Me.hDC, 0, Me.ScaleHeight - 74, Me.ScaleWidth, 74, Picture1.hDC, pX, 0, vbSrcCopy
pX = pX + 1
If pX > Picture1.Width Then pX = 0
End Sub



I am sure this will solve your problem :)
ASKER CERTIFIED SOLUTION
Avatar of Shahid Thaika
Shahid Thaika
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks!!!!!

I have now sucesfully integrated this with the hi-res timer code and have a very nicely smooth scrolling text scroller!

Best of Luck for your project :)