MFC CListCtrl解决闪烁问题(采坑无数)_mfc listctrl deleteitem 闪

第一步:在初始化时可设置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)
{
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值