Как избежать мерцания при рисовании

В чем заключается идея:
Мы рисуем не на главном контексте, а на вторичном (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);
}
 
« Предыдущая статья   Следующая статья »