CreateCompatibleDC
Creates a memory device context that is compatible with the device specified by pDC.
假如需要对屏幕进行比较多的gdi函数操作,如果每一步操作都直接对屏幕dc进行操作,那出现的大多数可能性都是屏幕的闪烁。一个很好的解决方法就是使用内存dc,将这些操作全部先在内存dc上操作,然后依次性在屏幕上进行操作。
例如:如果你单单使用bitblt在屏幕上拷贝一个图,那可以直接使用屏幕的dc。但是如果你要先设置背景(fillrect)然后再bitblt的话,这就涉及到两个屏幕dc的操作,这样的话屏幕很容易闪烁。
void CBounceWnd::OnTimer(UINT_PTR /* wParam */)
{
if (m_bmBall.m_hObject == NULL)
return; // no bitmap for the ball
CRect rcClient;
GetClientRect(rcClient);
CClientDC dc(this);
CBitmap* pbmOld = NULL;
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
pbmOld = dcMem.SelectObject(&m_bmBall);
dc.BitBlt(m_ptCenter.x - m_sizeTotal.cx / 2,
m_ptCenter.y - m_sizeTotal.cy / 2,
m_sizeTotal.cx, m_sizeTotal.cy,
&dcMem, 0, 0, SRCCOPY);
m_ptCenter += m_sizeMove;
if ((m_ptCenter.x + m_sizeRadius.cx >= rcClient.right) ||
(m_ptCenter.x - m_sizeRadius.cx <= 0))
{
m_sizeMove.cx = -m_sizeMove.cx;
}
if ((m_ptCenter.y + m_sizeRadius.cy >= rcClient.bottom) ||
(m_ptCenter.y - m_sizeRadius.cy <= 0))
{
m_sizeMove.cy = -m_sizeMove.cy;
}
dcMem.SelectObject(pbmOld);
dcMem.DeleteDC();
}