开发者

WM_TIMER animation flickering

开发者 https://www.devze.com 2023-04-11 20:44 出处:网络
Alright I\'m using a timer with a 50 ms elapse time to animate some moving text (technically its scrolling between text).

Alright I'm using a timer with a 50 ms elapse time to animate some moving text (technically its scrolling between text).

Problem is, if you look closely, you can see the text flickering, and id like it not to flicker..

So i'm not that good with animation but is there something I can do to reduce flickering? Maybe a faster elapse time? Or should I even be using a timer for this at all?

EDIT:

So i've tried to implement double buffering, and i'm obviously doing something.

Here is the code without double buffering, this works fine but flickers a little.

void PaintScrollingText(ScrollingText *Settings, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    HANDLE hOldFont;
    RECT rect;

    hdc = wParam ? (HDC)wParam : BeginPaint(Settings->hWnd, &ps);

    hOldFont = SelectObject(hdc, Settings->hFont);

    SetTextColor(hdc, Settings->crForeGnd);
    SetBkColor(hdc, Settings->crBackGnd);

    GetClientRect(Settings->hWnd, &rect);

    re开发者_如何学运维ct.right -= Settings->txt1XOffset;
    DrawText(hdc, Settings->szText1, -1, &rect, DT_RIGHT);

    rect.right += Settings->txt1XOffset - Settings->txt2XOffset;
    DrawText(hdc, Settings->szText2, -1, &rect, DT_RIGHT);

    SelectObject(hdc, hOldFont);

    if (!wParam) EndPaint(Settings->hWnd, &ps);
}

And this is my code, with double buffering.

void PaintScrollingText(ScrollingText *Settings, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    GetClientRect(Settings->hWnd, &rect);

    hdc = wParam ? (HDC)wParam : BeginPaint(Settings->hWnd, &ps);

    // Create off-screen DC
    HDC hdcMem = CreateCompatibleDC(hdc);

    // Create a bitmap to draw on
    HBITMAP MemBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);

    // Select bitmap into off-screen DC
    HGDIOBJ OldBitmap = SelectObject(hdcMem, MemBitmap);

    // Erase background
    HBRUSH hbrBkGnd = CreateSolidBrush(0x000000);
    FillRect(hdcMem, &rect, hbrBkGnd);
    DeleteObject(hbrBkGnd);

    // Set font and color
    HGDIOBJ hOldFont = SelectObject(hdcMem, Settings->hFont);
    SetTextColor(hdcMem, Settings->crForeGnd);
    SetBkColor(hdcMem, Settings->crBackGnd);

    // Draw text
    rect.right -= Settings->txt1XOffset;
    DrawText(hdcMem, Settings->szText1, -1, &rect, DT_RIGHT);

    rect.right += Settings->txt1XOffset - Settings->txt2XOffset;
    DrawText(hdcMem, Settings->szText2, -1, &rect, DT_RIGHT);

    // Blt the changes to the screen DC.
    BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcMem, 0, 0, SRCCOPY);

    // Select old font
    SelectObject(hdcMem, hOldFont);

    // Done with offscreen DC and bitmap
    SelectObject(hdcMem, OldBitmap);
    DeleteObject(MemBitmap);
    DeleteDC(hdcMem);

    if (!wParam) EndPaint(Settings->hWnd, &ps);
}

The first text is printed fine, but the second one looks like this:

WM_TIMER animation flickering

And here is the complete code without the double buffering: http://dl.dropbox.com/u/35314071/ScrollingTextClass.zip

And here is the complete code with the double buffering: http://dl.dropbox.com/u/35314071/ScrollingTextClass2.zip


Okay, I debugged the program (it's amazing what you can find if you just step through the code line by line), and at the point where you call BitBlt, you pass the parameters

BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcMem, 0, 0, SRCCOPY); 

Inspection of the values in the debugger shows that rect.right - rect.left is not the full size of the window but only part of it because you still have the value in rect.right left over from the line

rect.right += Settings->txt1XOffset - Settings->txt2XOffset;  

You forgot to set rect.right back to its original value.

rect.right += Settings->txt2XOffset;
0

精彩评论

暂无评论...
验证码 换一张
取 消