1. 使用SetRedraw禁止窗口重绘,操作完成后,再恢复窗口重绘
m_ctlList.SetRedraw(FALSE); //以下为更新数据操作 //…… //恢复窗口重绘 m_ctlList.SetRedraw(TRUE);
2. 使用LockWindowUpdate禁止窗口重绘,操作完成后,用UnlockWindowUpdate恢复窗口重绘
m_ctlList.LockWindowUpdate(); //以下为更新数据操作 //…… //恢复窗口重绘 m_ctlList.UnlockWindowUpdate();
m_ctlLisit.SetExtendedStyle(m_ctlLisit.GetExtendedStyle()|LVS_EX_DOUBLEBUFFER); VC6未定义LVS_EX_DOUBLEBUFFER宏,使用者可以自定义,如下: #define LVS_EX_DOUBLEBUFFER 0×00010000
首先要设置ListCtrl风格为LVS_REPORT | LVS_OWNERDATA或在ListCtrl属里中的More Styles页面中选中Owner data复选框。
其次要向应LVN_GETDISPINFO消息;
void OnGetdispinfoList(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM *pItem = &(pDispInfo)->item;
char szText[128] = {0};
if (pItem->mask & LVIF_TEXT)
{
//使缓冲区数据与表格子项对应
//m_ArrayBuff为二维数组
//定义如下 int m_ArrayBuff[2048][4];
_stprintf(szText,_T(“%d”),m_ArrayBuff[pItem->iItem][pItem->iSubItem]);
pItem->pszText = szText;
}
*pResult = 0;
}
最后便是生成缓冲区数据
void Insertdata()
{
//删除之前的数据
m_ctlList.SetItemCountEx(0);
m_ctlList.Invalidate();
m_ctlList.UpdateWindow();
srand( (unsigned)time( NULL ));
//生成新的数据缓冲区
int nItemCount = 2048;
for (int i = 0;i < nItemCount; i ++)
{
for (int k = 0;k < 4;k ++)
{
m_ArrayBuff[i][k] = rand()%2048 + 1;
}
}
if (nItemCount < 2)
{
m_ctlList.SetItemCountEx(1);
}
else
{
m_ctlList.SetItemCountEx(nItemCount);
}
m_ctlList.Invalidate();
}
若要修改数据,只要修改缓冲区m_ArrayBuff的数据即可以首先当然是重载CListCtrl类,设置ListCtrl属性"Owner Draw Fixed"为true,"Owner data"为false
(1). 并接管WM_ERASEBKGND消息,去掉默认的处理,改为不处理
手动添加重载消息ON_WM_ERASEBKGND()
BOOL CListCtrlEx::OnEraseBkgnd(CDC* pDC)
{
//响应WM_ERASEBKGND消息
return false;
//屏蔽默认处理
//return CListCtrl::OnEraseBkgnd(pDC);
}(2). 手动添加重载消息ON_WM_DRAWITEM()
void CListCtrlEx::OnPaint()
{
//响应WM_PAINT消息
CPaintDC dc(this); // device context for painting
CRect rect;
CRect headerRect;
CDC MenDC;//内存ID表
CBitmap MemMap;
GetClientRect(&rect);
GetDlgItem(0)->GetWindowRect(&headerRect);
MenDC.CreateCompatibleDC(&dc);
MemMap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
MenDC.SelectObject(&MemMap);
MenDC.FillSolidRect(&rect,RGB(228,236,243));
//这一句是调用默认的OnPaint(),把图形画在内存DC表上
DefWindowProc(WM_PAINT,(WPARAM)MenDC.m_hDC,(LPARAM)0);
//输出
dc.BitBlt(0,headerRect.Height(),rect.Width(), rect.Height(),&MenDC,0, headerRect.Height(),SRCCOPY);
MenDC.DeleteDC();
MemMap.DeleteObject();
}void DrawItem(_In_ LPDRAWITEMSTRUCT lpDrawItemStruct);
例如:这是我自己的的代码,可能你们有些符号找不到,这方面有疑问的话,可以咨询我QQ173708459,大家共同探讨
void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
LVITEM lvi = { 0 };
lvi.mask = LVIF_STATE | LVIF_IMAGE;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
lvi.iItem = lpDrawItemStruct->itemID; //表示菜单项ID,也可以表示列表框或者组合框中某项的索引值
BOOL bGet = GetItem(&lvi); //获取某些或全部列表视图项的属性
//颜色变量
COLORREF cTextColor;
COLORREF cBackColor;
//绘制区域
CRect rcBack = lpDrawItemStruct->rcItem;
int nWidth = rcBack.Width();
int nHeight = rcBack.Height();
//偏移图标位置(44*44),避免选中行时图标也被选中
rcBack.left += 48;
pDC->SetBkMode(TRANSPARENT);
//统一字体
CFont* OldFont = (CFont*)pDC->SelectObject(m_Font); //预先设置文本字体
//判断是否选中
BOOL bHighlight = ((lvi.state & LVIS_DROPHILITED) || ((lvi.state & LVIS_SELECTED) && ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS))));
//(1).先设置文本及背景色
if (bHighlight) //选中行
{
cTextColor = m_SelectItemTextColor;
cBackColor = m_SelectItemBackColor;
}
else if (lvi.iItem == m_nHoverIndex) //热点行
{
cTextColor = m_HoverItemTextColor;
cBackColor = m_HoverItemBackColor;
}
else
{
if (lpDrawItemStruct->itemID % 2) //奇数行
{
cTextColor = m_OddItemTextColor;
cBackColor = m_OddItemBackColor;
}
else //偶数行
{
cTextColor = m_EvenItemTextColor;
cBackColor = m_EvenItemBackColor;
}
}
//(2).再统一绘制颜色
pDC->SetTextColor(cTextColor);
pDC->FillRect(rcBack, &CBrush(cBackColor));
//(3).绘制文本内容
if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
{
//获取列数
CString szText;
int nCollumn = GetHeaderCtrl()->GetItemCount();
//循环得到文本
for (int i = 0; i < nCollumn; i++)
{
//获取子项矩形边界
CRect rcItem;
if (!GetSubItemRect(lvi.iItem, i, LVIR_LABEL, rcItem))
{
continue;
}
//获取子项文本内容
szText = GetItemText(lvi.iItem, i);
//绘制按钮
if (m_nListMark == LIST_INSTALL)
{
strTask_S *pTask = (strTask_S*)lpDrawItemStruct->itemData;
if (NULL != pTask)
{
if (i == 3) //绘制进度条
{
CRect rect(pTask->strProgress.rect);
if (!rect.IsRectEmpty())
{
//绘制边框
//CPoint point(5, 5);
CPen hNewPen(PS_SOLID, 1, RGB(217, 0, 0)); //RGB(217, 217, 217)
CPen* hOldPen = pDC->SelectObject(&hNewPen);
//pDC->RoundRect(&rect, point);
pDC->Rectangle(rect);
pDC->SelectObject(hOldPen);
hNewPen.DeleteObject();
//填充颜色
rect.top += 1;
rect.left += 1;
rect.right -= 1;
rect.bottom -= 1;
CString sInfo = "";
sInfo.Format("2.....%d\r\n", pTask->strProgress.uPercent);
OutputDebugString(sInfo);
int nLen = pTask->strProgress.uPercent * rect.Width() / 100;
sInfo.Format("3.....%d\r\n", nLen);
OutputDebugString(sInfo);
rect.right = rect.left + nLen;
CBrush brush(RGB(31, 210, 69));
pDC->FillRect(&rect, &brush);
//brush.DeleteObject();
//绘制文本
CRect rcText(pTask->strProgress.rect);
rcText.top = rcText.bottom + 8;
rcText.bottom = rcText.top + 13;
pDC->SetTextColor(RGB(153, 153, 153));
pDC->DrawText("已下载 0 B, 0 B/s", &rcText, DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
}
}
else if (i == 4) //绘制按钮
{
if (!pTask->strButtons.rect.IsRectEmpty())
{
//按钮边框
CPoint point(6, 6);
CPen hNewPen(PS_SOLID, 1, RGB(153, 153, 153));
CPen* hOldPen = pDC->SelectObject(&hNewPen);
CRect rect(pTask->strButtons.rect);
pDC->RoundRect(rect, point);
pDC->SelectObject(hOldPen);
hNewPen.DeleteObject();
//向内缩进
rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
//改用GDI+绘制,目的填充按钮渐变色
//定义一个线性渐变画刷,沿直线方向渐变,从上往下渐变
Point point1(rect.left, rect.top);
Point point2(rect.left, rect.bottom);
LinearGradientBrush linGrBrush(point1, point2, Color(255, 248, 248, 248), Color(255, 210, 210, 210));
Color colors[] = { Color(255, 220, 220, 220), Color(255, 200, 200, 200) }; //按红两种颜色渐变
REAL positions[] = { 0.0f, 0.5f }; //两种颜色,各占二分之一
linGrBrush.SetInterpolationColors(colors, positions, 2); //设置插补颜色(插值法)
Gdiplus::Graphics graphics(pDC->m_hDC);
graphics.FillRectangle(&linGrBrush, rect.left, rect.top, rect.Width(), rect.Height()); //填充区域
//绘制文本
Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 255));
Gdiplus::SolidBrush brush(Gdiplus::Color(255, 30, 30, 30)); //设置颜色和透明(0完全透明)/R/G/B
Gdiplus::FontFamily family(L"微软雅黑"); //设置字体 FontFamily fontFamily(L"Arial");
Gdiplus::Font font(&family, (Gdiplus::REAL)12, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); //FontStyleBold:粗体;FontStyleItalic:斜体;FontStyleUnderline:下划线
Gdiplus::PointF pointF((Gdiplus::REAL)rect.left + 12, (Gdiplus::REAL)rect.top + 2);
graphics.DrawString(CT2CW(pTask->strButtons.sTitle), -1, &font, pointF, &brush);
}
}
else //绘制文本
{
if (0 == i)
{
rcItem.left += 48 + 5; //跳过图标位置
}
pDC->DrawText(szText, lstrlen(szText), &rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
}
}
}
else if (m_nListMark == LIST_UPGRADE)
{
strAppInfo_S *pAppInfo = (strAppInfo_S*)lpDrawItemStruct->itemData;
if (NULL != pAppInfo)
{
if (i == 2) //设置按钮
{
if (!pAppInfo->strButtons.rect.IsRectEmpty())
{
//按钮边框
CPoint point(6, 6);
CPen hNewPen(PS_SOLID, 1, RGB(153, 153, 153));
CPen* hOldPen = pDC->SelectObject(&hNewPen);
CRect rect(pAppInfo->strButtons.rect);
pDC->RoundRect(rect, point);
pDC->SelectObject(hOldPen);
hNewPen.DeleteObject();
//向内缩进
rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
//改用GDI+绘制,目的填充按钮渐变色
//定义一个线性渐变画刷,沿直线方向渐变,从上往下渐变
Point point1(rect.left, rect.top);
Point point2(rect.left, rect.bottom);
LinearGradientBrush linGrBrush(point1, point2, Color(255, 248, 248, 248), Color(255, 210, 210, 210));
Color colors[] = { Color(255, 220, 220, 220), Color(255, 200, 200, 200) }; //按红两种颜色渐变
REAL positions[] = { 0.0f, 0.5f }; //两种颜色,各占二分之一
linGrBrush.SetInterpolationColors(colors, positions, 2); //设置插补颜色(插值法)
Gdiplus::Graphics graphics(pDC->m_hDC);
graphics.FillRectangle(&linGrBrush, rect.left, rect.top, rect.Width(), rect.Height()); //填充区域
//绘制文本
Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 255));
Gdiplus::SolidBrush brush(Gdiplus::Color(255, 30, 30, 30)); //设置颜色和透明(0完全透明)/R/G/B
Gdiplus::FontFamily family(L"微软雅黑"); //设置字体 FontFamily fontFamily(L"Arial");
Gdiplus::Font font(&family, (Gdiplus::REAL)12, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); //FontStyleBold:粗体;FontStyleItalic:斜体;FontStyleUnderline:下划线
Gdiplus::PointF pointF((Gdiplus::REAL)rect.left + 12, (Gdiplus::REAL)rect.top + 2);
graphics.DrawString(CT2CW(pAppInfo->strButtons.sTitle), -1, &font, pointF, &brush);
}
}
else //绘制文本
{
if (0 == i)
{
rcItem.left += 48 + 5; //跳过图标位置
}
pDC->DrawText(szText, lstrlen(szText), &rcItem, DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
}
}
}
}
}
//(4).重绘图标
Graphics graphics(pDC->m_hDC);
if (m_nListMark == LIST_INSTALL)
{
strTask_S *pTask = (strTask_S*)this->GetItemData(lvi.iItem);
if (pTask && pTask->pImageIcon)
{
Image *pImage = pTask->pImageIcon;
if (pImage)
{
graphics.DrawImage(pImage, 6, rcBack.top + 5, 36, 36);
}
}
else
{
graphics.DrawImage(g_pDefaultIcon, 6, rcBack.top + 5, 36, 36);
}
}
else if (m_nListMark == LIST_UPGRADE)
{
strAppInfo_S *pTask = (strAppInfo_S*)this->GetItemData(lvi.iItem);
if (pTask && pTask->pImageIcon)
{
Image *pImage = pTask->pImageIcon;
if (pImage)
{
graphics.DrawImage(pImage, 6, rcBack.top + 5, 36, 36);
}
}
else
{
graphics.DrawImage(g_pDefaultIcon, 6, rcBack.top + 5, 36, 36);
}
}
}
原文:http://blog.csdn.net/jiangqin115/article/details/44904085