Мерцание анимации WM_TIMER - PullRequest
       15

Мерцание анимации WM_TIMER

0 голосов
/ 07 октября 2011

Хорошо, я использую таймер со временем 50 мс для анимации движущегося текста (технически это прокрутка между текстом).
Проблема в том, что если вы посмотрите внимательно, вы можете увидеть мерцающий текст, и идентификатор какэто не мерцает ..

Так что я не так хорош с анимацией, но есть ли что-то, что я могу сделать, чтобы уменьшить мерцание?Может быть, быстрее пройдет время?Или я вообще должен использовать таймер для этого?

РЕДАКТИРОВАТЬ:
Итак, я попытался реализовать двойную буферизацию, и яочевидно, что-то делает.

Вот код без двойной буферизации, он отлично работает, но немного мерцает.

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 Ответ

6 голосов
/ 11 октября 2011

Хорошо, я отладил программу (это удивительно, что вы можете найти, если просто шаг за шагом проходите код), и в точке, где вы вызываете 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;
...