默认的列表控件绘制有很大的缺陷。但是有一个简单的技巧可以实现你自己的双缓冲技术:
CMyListCtrl::OnPaint()
{
CRect rcClient;
GetClientRect(rcClient);
CPaintDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmMem;
bmMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
CBitmap* pbmOld = dcMem.SelectObject(&bmMem);
dcMem.FillSolidRect(rcClient, ::GetSysColor(COLOR_WINDOW));
this->DefWindowProc(WM_PAINT, (WPARAM)dcMem.m_hDC, (LPARAM)0);
dc.BitBlt(0,0,rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pbmOld);
CHeaderCtrl* pCtrl = this->GetHeaderCtrl();
if (::IsWindow(pCtrl->GetSafeHWnd())
{
CRect aHeaderRect;
pCtrl->GetClientRect(&aHeaderRect);
pCtrl->RedrawWindow(&aHeaderRect);
}
}
这将创建一个位图,然后调用默认窗口过程将列表控件绘制到位图中,然后将位图的内容位图传输到绘制 DC。
您还应该为 WM_ERASEBKGND 添加一个处理程序:
BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
这将阻止控件在重绘之前始终擦除背景。如果您为位图添加一个成员变量并且仅在窗口大小发生变化时(重新)创建它(因为根据窗口大小,始终创建位图可能成本很高),您可以进一步优化 OnPaint。
这应该工作得很好。