473,387 Members | 1,611 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Scrolling text that doesn't flicker

Hi,
I have seen loads of different ways to do this, but the all seem to
yield the same result - text that doesn't flicker when it's moving too
slowly!
Does anyone know 'the best way' to make text scroll...

eg
Override OnPain and OnPaintBackground

Override WndProc

Use GDI

Use API

Or do i need to create some weird control in c++?!

Thanks in advance,
James

Nov 12 '06 #1
17 4670
"pigeonrandle" <pi**********@hotmail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Hi,
I have seen loads of different ways to do this, but the all seem to
yield the same result - text that doesn't flicker when it's moving too
slowly!
"Flicker" is generally caused by a single problem, regardless of what you're
drawing: erasing the previous image on-screen before drawing the new image.

Typically, this is addressed using an off-screen buffer to actually draw the
image, which is then copied directly to the screen without erasing whatever
was there previously. The reason you need to erase in the first place is to
get rid of whatever was there previously, but if you are always copying a
whole new bitmap (or portion of a bitmap) on top of every part of the
display that needs changing, then no erasing is necessary, and no flicker
occurs.

In .NET, I've been told one can enable "double-buffering" to address this.
The term "double-buffering" isn't correct, IMHO (it more correctly refers to
a related but different idea in which the entire screen buffer is switched
back and forth), but knowing that that's the phrase some .NET people use may
help you find the technique in the .NET documentation. I haven't used it
myself, so I can't tell you the specifics.

Pete
Nov 12 '06 #2
Hi James,

As Peter suggested, double buffering is an option to reduce flickering (the
only one I'm aware of as well). In the constructor of a class that derives
from Control (including the Form class) you can use the following code to
enable double buffering for that control (1.* applications):

this.SetStyle(ControlStyles.DoubleBuffer
| ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint, true);

In 2.0 apps, just set the Control.DoubleBuffered property to true (it uses the
new ControlStyles.OptimizedDoubleBuffer flag internally).

--
Dave Sexton

"pigeonrandle" <pi**********@hotmail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Hi,
I have seen loads of different ways to do this, but the all seem to
yield the same result - text that doesn't flicker when it's moving too
slowly!
Does anyone know 'the best way' to make text scroll...

eg
Override OnPain and OnPaintBackground

Override WndProc

Use GDI

Use API

Or do i need to create some weird control in c++?!

Thanks in advance,
James

Nov 13 '06 #3
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:up**************@TK2MSFTNGP03.phx.gbl...
Hi James,

As Peter suggested, double buffering is an option to reduce flickering
(the only one I'm aware of as well).
The other option is to just draw everything once. If you are doing something
like a chessboard this is easy, just draw each square onto the screen. If
the chessboard has pieces you could use regions to draw the pieces and then
draw the square around them. Unfortunately for text I don't think this is
possible. You have to use double buffering because it's not possible to draw
text with a background and it is not possible to find the region surrounding
this text. This also applies to many of the features of GDI+ such as
anti-aliasing and transparencies, it's no longer possible to draw in one go
so double buffering is almost mandatory these days.

Michael
Nov 13 '06 #4
Hi Michael,

But for scrolling text you can't draw everything only once. It's scrolling!

BTW, you can draw text with a background color in the 2.0 framework using the
TextRenderer class, which I believe uses GDI, not GDI+.

--
Dave Sexton

"Michael C" <no****@nospam.comwrote in message
news:u2**************@TK2MSFTNGP03.phx.gbl...
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:up**************@TK2MSFTNGP03.phx.gbl...
>Hi James,

As Peter suggested, double buffering is an option to reduce flickering (the
only one I'm aware of as well).

The other option is to just draw everything once. If you are doing something
like a chessboard this is easy, just draw each square onto the screen. If
the chessboard has pieces you could use regions to draw the pieces and then
draw the square around them. Unfortunately for text I don't think this is
possible. You have to use double buffering because it's not possible to draw
text with a background and it is not possible to find the region surrounding
this text. This also applies to many of the features of GDI+ such as
anti-aliasing and transparencies, it's no longer possible to draw in one go
so double buffering is almost mandatory these days.

Michael

Nov 13 '06 #5
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:O9**************@TK2MSFTNGP04.phx.gbl...
Hi Michael,

But for scrolling text you can't draw everything only once. It's
scrolling!
Yes, you can (assuming you can draw the background with the text as you
described). There will be x frames per second, for each frame if you draw
each pixel on the surface only once then you don't need double buffering.
BTW, you can draw text with a background color in the 2.0 framework using
the TextRenderer class, which I believe uses GDI, not GDI+.
If that's the case then it would be possible to use the API directly in 1.1,
although I don't recall there being an API that would let you draw text with
a background.

Michael
Nov 13 '06 #6
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:O9**************@TK2MSFTNGP04.phx.gbl...
But for scrolling text you can't draw everything only once. It's
scrolling!
The other thing you can do with scrolling text is use the ScrollWindow API
to move the contents of the window towards the left and then fill in the
invalid areas.

Michael
Nov 13 '06 #7
Hi Michael,
>But for scrolling text you can't draw everything only once. It's
scrolling!

Yes, you can (assuming you can draw the background with the text as you
described). There will be x frames per second, for each frame if you draw
each pixel on the surface only once then you don't need double buffering.
I really don't understand what you mean. How would that prevent Windows from
clearing the render target before the next operation?

I always thought double-buffering worked like the swap chain in DirectX, where
the back buffer is simply presented instead of the target being cleared.
Without the buffer, I assumed Windows will clear the target automatically for
each WM_PAINT message, causing a flicker.

Care to explain in more detail?
>BTW, you can draw text with a background color in the 2.0 framework using
the TextRenderer class, which I believe uses GDI, not GDI+.

If that's the case then it would be possible to use the API directly in 1.1,
although I don't recall there being an API that would let you draw text with
a background.
Yea, I'm not sure how they do it but it's there and it works (and it's GDI
according to the MSDN docs :)

--
Dave Sexton
Nov 13 '06 #8
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:O9**************@TK2MSFTNGP04.phx.gbl...
Hi Michael,

But for scrolling text you can't draw everything only once. It's
scrolling!
As Michael notes, in theory as long as you ensure that every pixel that
needs to change is drawn, you can avoid the flickering.

However...it's MUCH harder to accomplish this, and in some cases may be
impossible of course. Even with the original GDI, while it might have been
theoretically possible to draw the text, and fill the region outside the
text with the background color, that would have been such an expensive
drawing operation, no one sensible person would have done it that way.

The most common solution would have been to simply maintain a bitmap the
same size as the on-screen window, drawing into that and then blting the
results to the screen. Another solution would be to use smaller bitmaps,
the size of whatever it is you want to draw, blt those as they are drawn to
the appropriate spot on the screen. Of course, as was noted in Michael's
earlier post, if the kinds of things that are being drawn lend themselves to
simply copy an entire image to fill a specific area on the screen, then that
works too.

The key in all solutions is to avoid first clearing an area on the screen
and then drawing something else on top of that.
BTW, you can draw text with a background color in the 2.0 framework using
the TextRenderer class, which I believe uses GDI, not GDI+.
It's been awhile, but my recollection is that this doesn't make a
difference. That is, when drawing text with a background color (using the
opaque style), GDI would first fill in the background and then draw the
text, all directly to the destination DC. It didn't avoid flickering...it
just was more convenient than calling FillRect directly yourself (and also
had the advantage that you didn't have to measure the text first, since the
TextOut function handled the whole thing for you).

Even if using "double buffering" (sorry, I still hate that term as applied
here) could be avoided and dealing with updating screen graphics could be
solved some other way, IMHO there's not really any great reason to do so.
Using an off-screen bitmap, as in "double buffering", is a reasonably
elegant way to address a variety of complications that come up with any sort
of animated or changing display, and with the amount of RAM available on
most systems these days, doesn't incur much of a penalty.

Pete
Nov 13 '06 #9
"Michael C" <no****@nospam.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
The other thing you can do with scrolling text is use the ScrollWindow API
to move the contents of the window towards the left and then fill in the
invalid areas.
But those invalidated areas are cleared by the scrolling (or need to be
cleared when you fill them in), so that portion will still flicker.
Nov 13 '06 #10
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
>>But for scrolling text you can't draw everything only once. It's
scrolling!

Yes, you can (assuming you can draw the background with the text as you
described). There will be x frames per second, for each frame if you draw
each pixel on the surface only once then you don't need double buffering.

I really don't understand what you mean. How would that prevent Windows
from clearing the render target before the next operation?
He's saying that, if you had a way to ensure that each pixel on the screen
that has changed is drawn only once, setting it to the exact desired new
value, you can, once per frame, draw everything only once.

Obviously something animated has to be drawn multiple times. But the
flicker doesn't result from that. It results from drawing things multiple
times *per frame*. That's what he means to avoid.

In theory, it's even possible to do so (see my other post, about using
regions to mask the text area while filling the remaining background). In
reality, that's a) a much more complicated solution than using an off-screen
buffer, and b) may not even perform as well (since it would rely on using
regions to mask the text area while the background is being drawn).
I always thought double-buffering worked like the swap chain in DirectX,
where the back buffer is simply presented instead of the target being
cleared. Without the buffer, I assumed Windows will clear the target
automatically for each WM_PAINT message, causing a flicker.

Care to explain in more detail?
This is why I dislike the use of the term "double buffering" to describe
this. It's similar to, but not exactly the same as, the existing
double-buffering (or even triple-buffering, as is sometimes the case) used
in DirectDraw. In DirectDraw, double-buffering means there are two entire
frame buffers. One is always being used by the video card's RAMDAC to
display an image on the monitor, and the other is the one being drawn to at
that given moment. Once drawing has been completed, the entire active frame
buffer is switched (flipped), and the process starts anew.

This is kind of what the .NET "double buffering" is doing, except that it's
not a low-level hardware thing. There's an alternate, off-screen buffer and
rather than flipping the actively displayed buffer, the off-screen buffer is
simply copied to the active on-screen buffer. I don't like using the same
term for both, because it confuses the issue.

By doing this, any pixel that changes on the screen is drawn exactly once
for a given change (frame). Which is what needs to happen to avoid flicker.
And it certainly can happen that way, even as the text is scrolling. The
requirement is that the drawing happens once for each change, not that it
only happen once period.

Pete
Nov 13 '06 #11
Hi Peter,

Great explanation, thanks.

(You're not going to start billing me, right? ;)

--
Dave Sexton

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
>>>But for scrolling text you can't draw everything only once. It's
scrolling!

Yes, you can (assuming you can draw the background with the text as you
described). There will be x frames per second, for each frame if you draw
each pixel on the surface only once then you don't need double buffering.

I really don't understand what you mean. How would that prevent Windows
from clearing the render target before the next operation?

He's saying that, if you had a way to ensure that each pixel on the screen
that has changed is drawn only once, setting it to the exact desired new
value, you can, once per frame, draw everything only once.

Obviously something animated has to be drawn multiple times. But the
flicker doesn't result from that. It results from drawing things multiple
times *per frame*. That's what he means to avoid.

In theory, it's even possible to do so (see my other post, about using
regions to mask the text area while filling the remaining background). In
reality, that's a) a much more complicated solution than using an off-screen
buffer, and b) may not even perform as well (since it would rely on using
regions to mask the text area while the background is being drawn).
>I always thought double-buffering worked like the swap chain in DirectX,
where the back buffer is simply presented instead of the target being
cleared. Without the buffer, I assumed Windows will clear the target
automatically for each WM_PAINT message, causing a flicker.

Care to explain in more detail?

This is why I dislike the use of the term "double buffering" to describe
this. It's similar to, but not exactly the same as, the existing
double-buffering (or even triple-buffering, as is sometimes the case) used
in DirectDraw. In DirectDraw, double-buffering means there are two entire
frame buffers. One is always being used by the video card's RAMDAC to
display an image on the monitor, and the other is the one being drawn to at
that given moment. Once drawing has been completed, the entire active frame
buffer is switched (flipped), and the process starts anew.

This is kind of what the .NET "double buffering" is doing, except that it's
not a low-level hardware thing. There's an alternate, off-screen buffer and
rather than flipping the actively displayed buffer, the off-screen buffer is
simply copied to the active on-screen buffer. I don't like using the same
term for both, because it confuses the issue.

By doing this, any pixel that changes on the screen is drawn exactly once
for a given change (frame). Which is what needs to happen to avoid flicker.
And it certainly can happen that way, even as the text is scrolling. The
requirement is that the drawing happens once for each change, not that it
only happen once period.

Pete

Nov 13 '06 #12
Hi Peter,

Thank you.

So is there some double-buffer implementation in WPF that uses the hardware?

(I heard that WPF uses DirectX)

--
Dave Sexton

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:O9**************@TK2MSFTNGP04.phx.gbl...
>Hi Michael,

But for scrolling text you can't draw everything only once. It's
scrolling!

As Michael notes, in theory as long as you ensure that every pixel that
needs to change is drawn, you can avoid the flickering.

However...it's MUCH harder to accomplish this, and in some cases may be
impossible of course. Even with the original GDI, while it might have been
theoretically possible to draw the text, and fill the region outside the
text with the background color, that would have been such an expensive
drawing operation, no one sensible person would have done it that way.

The most common solution would have been to simply maintain a bitmap the
same size as the on-screen window, drawing into that and then blting the
results to the screen. Another solution would be to use smaller bitmaps,
the size of whatever it is you want to draw, blt those as they are drawn to
the appropriate spot on the screen. Of course, as was noted in Michael's
earlier post, if the kinds of things that are being drawn lend themselves to
simply copy an entire image to fill a specific area on the screen, then that
works too.

The key in all solutions is to avoid first clearing an area on the screen
and then drawing something else on top of that.
>BTW, you can draw text with a background color in the 2.0 framework using
the TextRenderer class, which I believe uses GDI, not GDI+.

It's been awhile, but my recollection is that this doesn't make a
difference. That is, when drawing text with a background color (using the
opaque style), GDI would first fill in the background and then draw the
text, all directly to the destination DC. It didn't avoid flickering...it
just was more convenient than calling FillRect directly yourself (and also
had the advantage that you didn't have to measure the text first, since the
TextOut function handled the whole thing for you).

Even if using "double buffering" (sorry, I still hate that term as applied
here) could be avoided and dealing with updating screen graphics could be
solved some other way, IMHO there's not really any great reason to do so.
Using an off-screen bitmap, as in "double buffering", is a reasonably
elegant way to address a variety of complications that come up with any sort
of animated or changing display, and with the amount of RAM available on
most systems these days, doesn't incur much of a penalty.

Pete

Nov 13 '06 #13
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
Hi Peter,

Great explanation, thanks.
You're welcome, of course.
(You're not going to start billing me, right? ;)
No way...if I started charging for this kind of stuff, I'd have to work a
lot harder to make sure I knew what I was writing about. :)

Pete
Nov 13 '06 #14
Hi Peter,

Work a lot harder?

I'm not sure why you're even working at all. You could be completely making
stuff up on some of these topics and I wouldn't be the wiser.

And you'd still get the credit ;)

--
Dave Sexton

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
>Hi Peter,

Great explanation, thanks.

You're welcome, of course.
>(You're not going to start billing me, right? ;)

No way...if I started charging for this kind of stuff, I'd have to work a
lot harder to make sure I knew what I was writing about. :)

Pete

Nov 13 '06 #15
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
But those invalidated areas are cleared by the scrolling (or need to be
cleared when you fill them in), so that portion will still flicker.
That's true, I guess all the same issues of double buffering or drawing with
a background would apply to those areas. This could still be useful as it
really speeds up scrolling, although could also complicate the issue.
>

Nov 13 '06 #16
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:O$**************@TK2MSFTNGP04.phx.gbl...
Hi Peter,

Work a lot harder?

I'm not sure why you're even working at all. You could be completely
making stuff up on some of these topics and I wouldn't be the wiser.

And you'd still get the credit ;)
Now you're catching on... :)
Nov 13 '06 #17
"Michael C" <no****@nospam.comwrote in message
news:eZ**************@TK2MSFTNGP03.phx.gbl...
>But those invalidated areas are cleared by the scrolling (or need to be
cleared when you fill them in), so that portion will still flicker.

That's true, I guess all the same issues of double buffering or drawing
with a background would apply to those areas. This could still be useful
as it really speeds up scrolling, although could also complicate the
issue.
It does speed up scrolling quite a lot (especially on large areas), and IMHO
is the appropriate method any time you simply need to scroll something on
the screen. I was just pointing out that it doesn't avoid other aspects of
the problem.

That said, because the flickering region is so small when using that
technique, the flicker is MUCH less noticable. In some cases, it might be
an appropriate solution...not because it eliminates flicker altogether, but
just because the user can barely notice what flicker does exist.

It really just depends on the particular situation. Funny how that keeps
coming up in these programming topics. :)

Pete
Nov 13 '06 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Marek Mänd | last post by:
This seems an IE issue only: 4253 bytes testcase: http://www.hot.ee/idaliiga/testcases/ieselect/bnlinkingselectinmsie.htm Can one have 1) a mouseover/mouseout element on TBODY 2) change in...
0
by: mp3boss | last post by:
I am updating a string in the format MM:SS every second using the On_Timer event in Access97 by changing the caption of a label. Even though I'm using 8point text, the box sometimes flickers...
0
by: Aku | last post by:
Hello, I have a RichTextBox located in a TabPage area; when I enter the RTBox space I displayed a certain text on it (using MouseEnter event). When I leave the RTBox space I displayed another...
0
by: alex sparsky | last post by:
I've written a small control that doesn't do much other than draw some things on the screen with the drawing classes. I am using double buffer as well as doing an internal drawing to buffer on a GDI...
3
by: seamlyne | last post by:
The first method I ever used for multiple state buttons was to create a graphic for each button for each state: AboutUs_on, AbooutUs_over, AboutUs_out, etc. That works great when there are just a...
13
by: WALDO | last post by:
I have a .Net TextBox (TextBoxBase, really) in which I am appending about 20 lines of text per second. I use the AppendText() method to accomplish this. This is a great substitute for taking the...
4
by: huntingseasonson | last post by:
Hi, I have set up the following page http://gertrudischale.com/cgi/ viewart.pl?lang=en&i=22 to scroll in the same direction one moves the mouse. This works fine -except in IE- where the image tends...
11
by: =?Utf-8?B?UmF5IE1pdGNoZWxs?= | last post by:
Hello, I know I sound like a one-note Johnny on this but I'm still looking for a solution. I need to display characters coming in from a serial port or a socket. I also need to be able to type...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.