Re: Scrolling text in a stationary label help needed

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



<jcrouse1@xxxxxxxxxxx> wrote in message
news:1158847323.638306.128910@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Mike, Well, after 3 hours of studying your examples and
notes and finally understanding what is happening I think
I got it. I also made the code more "portable" so you can
easier look at it. Does this look correct now? Any suggestions?

Nice one. It looks like you're almost there now. The code is performing a
single pixel scroll just once in each Timer event, which is exactly what you're
after. There are still a few problems, but they are only small ones.


Firstly, you are calling the routine that initiates the scroll in the
following manner:



ScrollText Label1.Left, Label1.Top, Label1.Width, Label1.Height



.. . . and then at the end of the ScrollText routine itself you are using
Label1.Width = 40. I don't think that is what you really meant to do. As far
as I can recall, your original requirement was to start off with a fixed
width Label (the width of which fits in nicely with whatever else it is you
have on the display) and then assign some text to it, centralising the text
in the visible transparent Label if it will fit and scrolling the text
inside a similarly sized "transparent" picture box if it will not fit. Is
that what you want to do?



If so, then your ScrollText routine should not itself mess about with the
width of the Label. The ScrollText routine should simply determine whether
the text fits fully inside the existing Label, displaying the Label if it
does, and displaying the "scrolling text in a transparent picture box" if it
does not. Your ScrollText routine is already performing most of that
function. To make it do it even better you need to remove the line from the
ScrollText routine that changes the Label's width.



Then you can do something like:



Label1.Width = 40 ' (or whatever you wish)

Label1.Text = "ABCDEFGHIJKLMNOP" ' (or whatever)

ScrollText Label1.Left, Label1.Top, Label1.Width, Label1.Height



Also, unless by chance the Picture Box font settings just happen to be the
same as the Label's font settings, your existing code is going to come up
with the wrong answer when it performs the test:



If Picture1.TextWidth(stext) > Label1.Width Then



.. . . this is because you are setting up the picture box font details
*after* performing that test, instead of before it. To fix this you need to
move all of the code that does things like "Picture1.Font.Something" =
Label1.Font.Something" and all of the code that performs similar things with
the italic and bold settings, all of that code needs to be *before* the "If
.. . . Then" statement.



Post again when you've got all that stuff sorted and you can then look at
using arrays of Labels and Picture Boxes instead, so that you can have as
many "scrolling labels" as you wish.



Although I don't fully understand the DX stuff

the concept of the timer is quite simple.



I'm not sure how much you know about monitors and TVs, and of course things
have changed quite a lot now that most people use modern flat panel monitors
instead of the older CRT TV tubes, but the basic idea of "a series of
individual frames" is still much the same, although the details of precisely
how that is accomplished have changed a lot. Looking specifically at a CRT
display, and without going into to much detail, the picture on the screen is
created by a single very bright moving dot of light that travels rapidly
across the width of the screen drawing a "line of pixels" and then moves
down one pixel and draws another horizontal line until it has eventually
drawn a series of horizontal "scan lines" that completely fill the screen.
That entire set of scan lines that completely fill the display is called a
"frame". You don't see this happening of course, because of the persistence
of the phosphor and of the human eye. There is then a short delay while the
very bright dot travels vertically back up the screen to the top left
starting position, when the whole process is repeated. During this "flyback
period" when the dot is travelling vertically back to the top of the screen
the energy of the dot (the electronic beam) is reduced to almost zero, so
that it does not create a trace. This is called the "vertical blank" period.
On a CRT monitor that is attached to a computer that happens to be running
at a 75 Hz display refresh rate these "individual frames" and the "vertical
blanks" that follow them both occur at a rate of 75 "frames per second".



Now think about an object that is repeatedly being drawn to the display at
slightly different positions (your single pixel scrolling text, for
example). If you simply run the code from a Timer or a timed loop or
whatever there is no way that you will ever manage to get the timing to
exactly correspond to the video "frame rate" (75 frames per second in the
above example). Even if you get it very close you will not get it exact,
especially because the source of your Timer (the "clock" that is driving it)
is completely separate from the "clock" that is driving the video display.
In most cases this doesn't really matter, but in some cases it can be a
problem (in the example of a single pixel scrolling text it would cause the
scroll to appear to "judder"). Even if you got the timing "almost
exactly"correct (which is the best you can do with a standard Timer) there
would still be "judder". Sometimes the object would be drawn at a specific
position just after the frame drawing "bright dot" had passed that position
(in which case it would not be shown at that position in that frame) and
sometimes it would be drawn twice in succession in the time between frames.
I'm simplifying this a little, but the overall effect would be that the
object would move "on average" one pixel per frame, but sometimes it would
move two pixels and sometimes it would not move any pixels at all. (I hope I
haven't gone too far into this stuff John, but you did ask me!).



Anyway, the "objDD.WaitForVerticalBlank" code causes your VB progam to wait
until the current frame has been completely drawn and the "bright dot" that
draws it is blanked and is moving vertically back up to the top left ready
to draw the next frame. (This is on a CRT monitor of course. Flat panel
displays work in very different manner, but the reasoning is still much the
same). So, WaitVerticalBlank effectively "locks your code repeat rate" to
exactly the frame rate of the video card. This produces extremely smooth
animation of your scrolling text. Of course in a multitasking system such a
Windows nothing works quite like that, but as you will no doubt see the
WaitVerticalBlank line can make quite a difference to the smoothness of your
scrolling.



There is a price to be paid for this of course (at least in the Timer code
you are using). If, for example, your Timer is running at a 10 millisecond
period and your video card is running at 13.3 millisecond period (75 Hz
refresh rate) then the timer event code will "hang around" for about 3.3
milliseconds every time, whereas if you didn't use WaitVerticalBlank the
rest of your code could use that 3.3 milliseconds to do something else. This
is hardly likely to be a problem in most applications though. You cannot get
less than a 10 millisecond period out of the VB Timer Control (in fact if
you are using Win98 you cannot get less than a 55 millisecond period out of
it). Also, other users of your application might be using computers where
the video frame rate gives you less than 10 milliseconds to work with.
Additionally, you will find various Win XP systems that will not give you 10
milliseconds from the VB Timer (15 milliseconds is fairly common or at least
it used to be). So, if you want your code to run well and achieve such
smooth scrolling under all conditions on all systems you really need to be
using a higher resolution Timer. You can then write code to determine the
user video refresh rate at run time (a single For Next loop with
WaitVerticalBlank in it will do that job for you) and you can then set the
high resolution Timer period to be a little less than the video frame period
(allowing for the execution time of whatever code you put in there).



Of course in most applications it is common to simply animate things at the
rate you desire without worrying too much about the video frame rate. Most
"natural looking" animations move things at rates that would not "tie in
exactly" with the video frame rate anyway, and in most animations (people
running, cars and planes moving around and things) objects move at rates
which are determined by other quite separate factors. This is fine. It is
only in certain special things, like "single pixel scrolling text" where
locking the scroll to the frame rate is desirable.



There's lots more to be said about this stuff of course, but I think I'll
leave it at that. I expect that by now you're sorry you ever asked about the
WaitVerticalBlank stuff ;-)



Mike




.



Relevant Pages

  • Re: Turning off some messages - is it possible? Is it unnecessary?
    ... However, in the gaming domain, responsiveness (not efficiency) is the problem. ... >10ms per frame. ... the first thing I did was create a timer to ... MVP Tips: http://www.flounder.com/mvp_tips.htm ...
    (microsoft.public.vc.mfc)
  • Re: make your posting readable
    ... go to the trouble of scrolling down to try to pick out whatever ... immediately forget what you just read, bottom-posting makes no ... Since it takes a lot of extra time to switch from frame to frame ... new in the first frame. ...
    (sci.electronics.repair)
  • Re: Smooth scrolling of Bitmaps
    ... The obvious solution is to set the timer to fire at a regular interval, ... I currently display a bitmap within a portion of a window. ... The scrolling is not very smooth. ... I came across ScrollWindowExand the SW_SMOOTHSCROLL flag but when I ...
    (microsoft.public.win32.programmer.ui)
  • Re: LXI, IEEE1588 and TTP
    ... > addition to these protocols. ... A sends a synchronisation frame to B and starts a timer when ... B reads the time at wich it receives the character and starts ... B sends a reply frame, reads the timer when the equivalent ...
    (comp.arch.embedded)
  • Re: paste image into a form
    ... computer literate of folk. ... than scrolling around. ... i'll try the frame / scrollbar approach and see if that will do. ... > Andy Pope, Microsoft MVP - Excel ...
    (microsoft.public.excel.programming)