https://blog.csdn.net/jiangqin115/article/details/44904085
https://my.oschina.net/laopiao/blog/99320
https://bbs.csdn.net/topics/100134274
此几处虽介绍了几种方法,但实际并不好用。中间踩坑过程我不赘述了。这里要注意CListCtrl与CMFCListCtrl有所区别,区别在于CListCtrl的GetHeaderCtrl()返回的是指针,而CMFCListCtrl的GetHeaderCtrl返回的是引用。此外,这里容易漏写消息的注册,需要特别注意。
第一步:在初始化时可设置style或者新建控件时候设置。OnInitDialog()中
DWORD style = list1_.GetExtendedStyle();
style |= LVS_EX_FULLROWSELECT;
style |= LVS_EX_GRIDLINES;
style |= LVS_EX_FLATSB;
style |= LVS_EX_DOUBLEBUFFER;
style |=LVS_REPORT ;
style |=LVS_OWNERDATA;
list1_.SetExtendedStyle(style);
第二步:重写此类,
//CMyListCtrl.h
#pragma once
#include "afxcmn.h"
class CMyListCtrl :
public CListCtrl
{
DECLARE_DYNAMIC(CMyListCtrl)
public:
CMyListCtrl(void);
~CMyListCtrl(void);
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
public:
CString GetItemText(int nItem, int nSubItem) const;
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
private:
CDC* m_pDC;
};
//CMyListCtrl.cpp
#include "StdAfx.h"
#include "MyListCtrl.h"
IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl)
CMyListCtrl::CMyListCtrl(void)
{
m_pDC = NULL;
}
CMyListCtrl::~CMyListCtrl(void)
{
if (!m_pDC)
{
delete m_pDC;
m_pDC = NULL;
}
}
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void CMyListCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
CRect headerRect;
CDC MenDC;
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(255,255,255));
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();
}
BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
CString CMyListCtrl::GetItemText(int nItem, int nSubItem) const
{
ASSERT(::IsWindow(m_hWnd));
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = nSubItem;
CString str;
int nLen = 512;
int nRes;
do
{
nLen *= 2;
lvi.cchTextMax = nLen;
lvi.pszText = str.GetBufferSetLength(nLen);
nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
(LPARAM)&lvi);
} while (nRes >= nLen-1);
str.ReleaseBuffer();
return str;
}
void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem(lpDrawItemStruct->rcItem);
int nItem = lpDrawItemStruct->itemID;
COLORREF clrTextSave, clrBkSave;
static _TCHAR szBuff[1024];
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_STATE;//LVIF_IMAGE |
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
lvi.stateMask = 0xFFFF;
GetItem(&lvi);
BOOL bSelected = (lvi.state & LVIS_SELECTED);
CRect rcAllLabels;
GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS);
if (bSelected)
{
clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
GetItemRect(nItem, rcItem, LVIR_LABEL);
pDC->DrawText(szBuff, -1, rcItem, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
for (int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
{
rcItem.left = rcItem.right;
rcItem.right += lvc.cx;
int nRetLen = CListCtrl::GetItemText(nItem, nColumn,
szBuff, sizeof(szBuff));
if (nRetLen == 0)
continue;
UINT nJustify = DT_LEFT;
switch (lvc.fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_RIGHT:
nJustify = DT_RIGHT;
break;
case LVCFMT_CENTER:
nJustify = DT_CENTER;
break;
default:
break;
}
pDC->DrawText(szBuff, -1, rcItem,
nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
}
if (lvi.state & LVIS_FOCUSED)
pDC->DrawFocusRect(rcAllLabels);
if (bSelected)
{
pDC->SetTextColor(clrTextSave);
pDC->SetBkColor(clrBkSave);
}
}**
第三步、在更新数据的地方进行以下操作,例如,此处我在OnTimer中更新数据,以下为伪代码,可自行根据场景修改。
void CMyDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent==1)
{
listCtrl.SetRedraw(FALSE);
LVFINDINFO lv;
lv.flags=LVFI_STRING;
lv.psz=pid.c_str();
int nItem=list1_.FindItem(&lv,-1);
if (nItem < 0)
{
list1_.InsertItem(i, str, i);
}
else if (nItem ==0)
{
continue;
}
listCtrl.SetItemText(i, 1, name.c_str());
listCtrl.SetItemText(i, 2, pid.c_str());
listCtrl.SetItemText(i, 3, ip.c_str());
listCtrl.SetImageList(&m_imagelist_s, LVSIL_SMALL); //把m_Imagelist 关联给列表框。
vlistCtrl.SetRedraw(TRUE);
}
}