我扩展了一个CListCtrl类,通过DrawItem来绘制单元格,进度条的功能,现在代码实现了,但是会有闪烁,拉动滚动条的时候会闪烁,更新单元格还是会闪烁,请问大侠们,我哪里写错了么?我通过双缓冲来绘制背景代码如下:
BOOL CListCtrlex::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rc;
GetWindowRect(&rc);
CDC CMDC;
CMDC.CreateCompatibleDC(NULL);
CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height()); CBitmap * oldbmp =CMDC.SelectObject(&bmp);
BITMAP bm;
bmp.GetBitmap(&bm);
CMDC.FillSolidRect(0,0,rc.Width(),rc.Height(),m_refdefbkColor);
pDC->StretchBlt(0,0,rc.Width(),rc.Height(),&CMDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
CMDC.SelectObject(oldbmp);
bmp.DeleteObject();
CMDC.DeleteDC(); return TRUE;// CListCtrl::OnEraseBkgnd(pDC);
}DrawItem函数中绘制单元格 代码如下:
void CListCtrlex::DrawItem(LPDRAWITEMSTRUCT lpItemStruct)
{ // TODO: 添加您的代码以绘制指定项
int nItem=lpItemStruct->itemID;
if(nItem==-1)
{
return;
}
else
{
//DEFAULT_GUI_FONT
CString strText;
CDC * pDC=CDC::FromHandle(lpItemStruct->hDC); LVITEM item;
item.iItem=nItem;
item.iSubItem=0;
item.mask=LVIF_IMAGE|LVIF_STATE;
item.stateMask=0XFFFF;
GetItem(&item);
BOOL bSelect=item.state&LVIS_SELECTED;
CFont font;
COLORREF bkColor;
COLORREF txtColor ;
if(bSelect)
{
bkColor = m_refselbkColor;
txtColor= m_refselTextColor;
}
else
{
bkColor = m_refdefbkColor;
txtColor = m_refdefTextColor;
}
LV_COLUMN lvc;
lvc.mask=LVCF_FMT|LVCF_WIDTH ;
for(int nCol=0;this->GetColumn(nCol,&lvc);nCol++)
{
CRect rcItem;
GetSubItemRect(lpItemStruct->itemID, nCol, LVIR_LABEL, rcItem);
bool bProcess =false;
set<int>::const_iterator itr = m_ProcessCol.find(nCol); if(itr != m_ProcessCol.end())
bProcess = true; strText = GetItemText(lpItemStruct->itemID, nCol); CDC CMDC;
CMDC.CreateCompatibleDC(NULL);
CBitmap * oldbmp = NULL;
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rcItem.Width(),rcItem.Height()); CRect rcCurrentRect;
CRect rcbmp(5,0,rcItem.Width(),rcItem.Height());
oldbmp =CMDC.SelectObject(&bmp);
CMDC.SetBkMode(TRANSPARENT);
CFont * pOldfont= CMDC.SelectObject(&m_font);
BITMAP bm ;
bmp.GetBitmap(&bm);
if (bProcess)
{
float with=(float)atof(strText)/100 *rcItem.Width();
CMDC.FillSolidRect(0,0,rcItem.Width(),rcItem.Height(),m_refProcbkColor);
CMDC.FillSolidRect(0,1,with,rcItem.Height(),m_refProcColor);
CMDC.SetTextColor(txtColor); if (strText.Trim()!="")
{
strText+="%";
}
else
{
strText="0%";
}
::SetRect(&rcCurrentRect,rcItem.left,rcItem.top,rcItem.left+(int)with,rcItem.bottom);
CMDC.DrawText(strText,&rcbmp,DT_CENTER|DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);
pDC->StretchBlt(rcCurrentRect.left,rcCurrentRect.top,rcItem.Width(),rcItem.Height(),
&CMDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
}
else
{
CMDC.FillSolidRect(0,0,rcItem.Width(),rcItem.Height(),bkColor);
CMDC.DrawText(strText,&rcbmp,DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);
pDC->StretchBlt(rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height(),&CMDC,0,0,bm.bmWidth,
bm.bmHeight,SRCCOPY);
} CMDC.SelectObject(oldbmp);
CMDC.SelectObject(pOldfont);
bmp.DeleteObject();
CMDC.DeleteDC();
}
}
}
BOOL CListCtrlex::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rc;
GetWindowRect(&rc);
CDC CMDC;
CMDC.CreateCompatibleDC(NULL);
CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height()); CBitmap * oldbmp =CMDC.SelectObject(&bmp);
BITMAP bm;
bmp.GetBitmap(&bm);
CMDC.FillSolidRect(0,0,rc.Width(),rc.Height(),m_refdefbkColor);
pDC->StretchBlt(0,0,rc.Width(),rc.Height(),&CMDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
CMDC.SelectObject(oldbmp);
bmp.DeleteObject();
CMDC.DeleteDC(); return TRUE;// CListCtrl::OnEraseBkgnd(pDC);
}DrawItem函数中绘制单元格 代码如下:
void CListCtrlex::DrawItem(LPDRAWITEMSTRUCT lpItemStruct)
{ // TODO: 添加您的代码以绘制指定项
int nItem=lpItemStruct->itemID;
if(nItem==-1)
{
return;
}
else
{
//DEFAULT_GUI_FONT
CString strText;
CDC * pDC=CDC::FromHandle(lpItemStruct->hDC); LVITEM item;
item.iItem=nItem;
item.iSubItem=0;
item.mask=LVIF_IMAGE|LVIF_STATE;
item.stateMask=0XFFFF;
GetItem(&item);
BOOL bSelect=item.state&LVIS_SELECTED;
CFont font;
COLORREF bkColor;
COLORREF txtColor ;
if(bSelect)
{
bkColor = m_refselbkColor;
txtColor= m_refselTextColor;
}
else
{
bkColor = m_refdefbkColor;
txtColor = m_refdefTextColor;
}
LV_COLUMN lvc;
lvc.mask=LVCF_FMT|LVCF_WIDTH ;
for(int nCol=0;this->GetColumn(nCol,&lvc);nCol++)
{
CRect rcItem;
GetSubItemRect(lpItemStruct->itemID, nCol, LVIR_LABEL, rcItem);
bool bProcess =false;
set<int>::const_iterator itr = m_ProcessCol.find(nCol); if(itr != m_ProcessCol.end())
bProcess = true; strText = GetItemText(lpItemStruct->itemID, nCol); CDC CMDC;
CMDC.CreateCompatibleDC(NULL);
CBitmap * oldbmp = NULL;
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rcItem.Width(),rcItem.Height()); CRect rcCurrentRect;
CRect rcbmp(5,0,rcItem.Width(),rcItem.Height());
oldbmp =CMDC.SelectObject(&bmp);
CMDC.SetBkMode(TRANSPARENT);
CFont * pOldfont= CMDC.SelectObject(&m_font);
BITMAP bm ;
bmp.GetBitmap(&bm);
if (bProcess)
{
float with=(float)atof(strText)/100 *rcItem.Width();
CMDC.FillSolidRect(0,0,rcItem.Width(),rcItem.Height(),m_refProcbkColor);
CMDC.FillSolidRect(0,1,with,rcItem.Height(),m_refProcColor);
CMDC.SetTextColor(txtColor); if (strText.Trim()!="")
{
strText+="%";
}
else
{
strText="0%";
}
::SetRect(&rcCurrentRect,rcItem.left,rcItem.top,rcItem.left+(int)with,rcItem.bottom);
CMDC.DrawText(strText,&rcbmp,DT_CENTER|DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);
pDC->StretchBlt(rcCurrentRect.left,rcCurrentRect.top,rcItem.Width(),rcItem.Height(),
&CMDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
}
else
{
CMDC.FillSolidRect(0,0,rcItem.Width(),rcItem.Height(),bkColor);
CMDC.DrawText(strText,&rcbmp,DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);
pDC->StretchBlt(rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height(),&CMDC,0,0,bm.bmWidth,
bm.bmHeight,SRCCOPY);
} CMDC.SelectObject(oldbmp);
CMDC.SelectObject(pOldfont);
bmp.DeleteObject();
CMDC.DeleteDC();
}
}
}
调用InvalidateRect(&cliprc)
应该在你改变窗口内容时调用,你要计算出有多大的rect需要重绘。重绘背景的地方不必改,因为重绘只能在这个rect内,其他地方的重绘不起作用。