tags:

views:

112

answers:

3

hello,

i would like to have text that scrolls smoothly on my c# windows form.

i tried to define that label with text on it moves pixel by pixel, but it is not smooth as it is like animations created in flash.

how can i manage to get such smooth animation?

thank you in advance!

A: 

I assumed that you use double buffering, because without it, your text WILL blink and won't look very nice at all.

There is the issue with GDI that you probably have, and that's you moving speed isn't synced with monitor refresh rate.

If you have 60Hz LCD monitor for example, you should update text position every 1000/60 ms, but if you use timer for that, you'll experience jerkiness now and then.

Daniel Mošmondor
This would cause it to flash, instead of not being smooth enough, and could be solved by turning double buffering on.
treaschf
I assumed that double buffering is used - without it it would really look very very bad.
Daniel Mošmondor
A: 

If you override the read-only property CreateParams on your form and add WX_COMPOSITE ( 0x2000000, I think that is composite ) to the params. This only works on XP and up, but it stops flickering where DoubleBuffer doesn't.

Kogitsune
+2  A: 

I have tried to do it and I've got some good news and some bad news.

The good news is that it is possible. I am testing the code right now and I can achieve absolutely silky smooth text scrolling even with GDI+.

The tough part is that there are quite a few things you must ensure / implement to have it:

  1. Set DoubleBuffered to true on your rendering surface (e.g. your form).
  2. You have to draw the text yourself, the Label class will not do (see next point as to why).
  3. You need floating point resolution in your drawing (positioning) code, which means you must use TextRenderingHint.AntiAlias in your DrawString() calls and bigger font sizes (>10-12 pt) to make it look good.
  4. You need a very high resolution timer component. I am using a component based on Win32 multimedia timers in winmm.dll that allows for timer event rates up to 1000 Hz and almost absolute accuracy (standard deviation below 0.1 ms). Google for MultimediaTimer component. (BTW, I know it is no longer the solution recommended by MS, but it works perfectly even in Windows 7.)
  5. Also, the Windows multimedia timer has a millisecond resolution, which cannot give you perfect 60 Hz refresh (1000/60 is not an integer), so you will need to implement some kind of a floating point display refresh counting mechanism to get as close to the display refresh rate as possible. Something along the lines of

    float tickCount = 0.0f;
    float tickDelta = 1000.0f / 60.0f;
    
    
    void mmTimer_Tick(object sender, EventArgs e)
    {
        tickCount++;
        if (tickCount >= tickDelta)
        {
            tickCount -= tickDelta;
            // scroll your text here 
            Invalidate();
        }
    }
    

    will do.

  6. Finally, some minor tearing might happen occasionally. This is all but inevitable, as you have no access to vertical sync video registers. Experiment with timings to eliminate tearing.

I honestly hope this helps. Let me know if you have any problems implementing it.

Alan
for me it's ok if i work not with labels, but with images. i guess that i can implement your solution on sliding image?
@user198003: Sure, it will work with any graphic object. I used DrawString() in the rendering code, but any System.Drawing.Graphics method will work. Don't make the image too large, though, or you'll see more tearing regardless of the scrolling speed (remember, there is no VSync without DirectX).
Alan