WM_TIMER animation flickering
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:
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.zipOkay, 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;
精彩评论