В чем заключается идея: Мы рисуем не на главном контексте, а на вторичном (backbuffer), а затем переносим его содержимое на главный.
з.ы. Там есть такая фенечка #define DISPLAY (чтобы это увидить, но убрать строку #undef DISPLAY дык вот, она затем, если мы вдруг захотим увидить, что же делается в нашем вторичном контексте, а для этого выводим его на экран (DISLPAY).
з.з.ы Этот код дает общее понятие о том, как это делается и не более того, т.е. надо кучу проверок вставить и т.д. void CALLBACK TimerProc( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time ) { RECT rect; GetClientRect (GetDlgItem (AfxGetApp ()->m_pMainWnd->m_hWnd, IDC_STATIC), &rect); static double width = rect.right; static double height = rect.bottom; HDC dc = GetDC (GetDlgItem (AfxGetApp ()->m_pMainWnd->m_hWnd, IDC_STATIC));
#define DISPLAY #undef DISPLAY
#if defined DISPLAY HDC hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); #else HDC hdc = CreateCompatibleDC (dc); HBITMAP hBitmap = CreateCompatibleBitmap (hdc, rect.width, rect.height); SelectObject (hdc, hBitmap); #endif FillRect(hdc, &rect, (HBRUSH) (COLOR_WINDOW+1)); Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom); MoveToEx (hdc, rect.right/2, (int)rect.bottom/2, NULL); LineTo (hdc, (int)((cos(width+=0.01)+1)*120), (int)((sin(height+=0.01)+1)*120)); MoveToEx (hdc, rect.right/2, (int)rect.bottom/2, NULL); LineTo (hdc, (int)((sin(width)+1)*120), (int)((cos(height)+1)*120)); BitBlt (dc, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY); #if !defined DISPLAY DeleteObject (hBitmap); #endif ReleaseDC (GetDlgItem (AfxGetApp ()->m_pMainWnd->m_hWnd, IDC_STATIC), dc); DeleteDC (hdc); }
void CDrawDlg::OnBnClickedButton1() { SetTimer (1000, 10, TimerProc); }
void CDrawDlg::OnBnClickedButton2() { KillTimer (1000); } |