WM_TIMER动画闪烁

时间:2011-10-06 21:40:34

标签: c++ windows animation timer double-buffering

好吧我正在使用一个时间为50毫秒的计时器来动画一些移动文本(技术上它在文本之间滚动)。
问题是,如果你仔细观察,你可以看到文字闪烁,并且id不喜欢闪烁..

所以我对动画不是那么好但是我能做些什么来减少闪烁?也许更快的过去时间?或者我是否应该使用计时器呢?

编辑:
所以我试图实现双缓冲,我显然正在做点什么。

这是没有双缓冲的代码,这个工作正常,但有点闪烁。

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);

    rect.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);
}

这是我的代码,双缓冲。

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);
}

第一个文本打印正常,但第二个文本看起来像这样:

这是没有双缓冲的完整代码:http://dl.dropbox.com/u/35314071/ScrollingTextClass.zip
这里是带有双缓冲的完整代码:http://dl.dropbox.com/u/35314071/ScrollingTextClass2.zip

1 个答案:

答案 0 :(得分:6)

好的,我调试了程序(如果你只是逐行浏览代码,那就太棒了),在你调用BitBlt的时候,你传递了参数

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

检查调试器中的值会显示rect.right - rect.left不是窗口的完整大小,而只是其中的一部分,因为您仍然在行中遗留了rect.right中的值

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

您忘记将rect.right设置回其原始值。

rect.right += Settings->txt2XOffset;