CListCtrl 虚拟列表实现

19 篇文章 0 订阅

a、创建时添加 LVS_OWNERDATA

例如:

p_list_History->Create(LVS_SINGLESEL|LVS_REPORT|LVS_ALIGNLEFT|WS_BORDER|LVS_OWNERDATA ,CRect(left,top,right,bottom),this,IDC_LIST_HISTORY);
p_list_History->SetExtendedStyle(p_list_History->GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

b、对话框或者CListCtrl 子类响应三个消息
  

    ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST_ALARM, OnGetdispinfoList)
    ON_NOTIFY(LVN_ODFINDITEM, IDC_LIST_ALARM, OnOdfinditemList)
    ON_NOTIFY(LVN_ODCACHEHINT, IDC_LIST_ALARM, OnOdcachehintList)

c、实现对应的三个函数,具体获取的值可以调试,建议用vector,map好像不行。

如:

//虚表要实现的函数之一
void CNavigationDialog::OnGetdispinfoList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

	//Create a pointer to the item
	LV_ITEM* pItem= &(pDispInfo)->item;

	//Which item number?
	int itemid = pItem->iItem;

	//主机地址
	int nZJ_address = g_vector_alarm[itemid].bjq_zj_address;

	//Do the list need text information?
	if (pItem->mask & LVIF_TEXT)
	{
		CString text;

		//Which column?
		if(pItem->iSubItem == 0)
		{
			//Text is name 序号
			text.Format("%d",itemid+1);
		}
		else if (pItem->iSubItem == 1)
		{
			//Text is slogan
			//所在区域
			text = GetAreaNameByZJAddress(nZJ_address);
			if (text.Compare("jh")==0)
			{
				text = "焦化分厂";
			}
		}
		else if (pItem->iSubItem == 2)
		{
			//主机名称
			text = GetZJName(g_vector_alarm[itemid].bjq_zj_address);
		}
		else if (pItem->iSubItem == 3)
		{
			//报警仪的名称/位置
			text = GetBJQName(g_vector_alarm[itemid].bjq_zj_address,atoi(g_vector_alarm[itemid].bjq_address));
		}
		else if (pItem->iSubItem == 4)
		{
			//气体类型
			text = g_vector_alarm[itemid].bjq_Gas_type;
		}
		else if (pItem->iSubItem == 5)
		{
			//状态
			text = g_vector_alarm[itemid].bjq_state;
		}
		else if (pItem->iSubItem == 6)
		{
			//时间
			text = g_vector_alarm[itemid].dateTime;
		}

		//Copy the text to the LV_ITEM structure
		//Maximum number of characters is in pItem->cchTextMax
		lstrcpyn(pItem->pszText, text, pItem->cchTextMax);
	}
	*pResult = 0;
}

//虚表要实现的函数之二
//This functions is called when the user "writes" in the list box to find an item.
void CNavigationDialog::OnOdfinditemList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// pNMHDR has information about the item we should find
	// In pResult we should save which item that should be selected
	NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)pNMHDR;

	/* pFindInfo->iStart is from which item we should search.
	We search to bottom, and then restart at top and will stop
	at pFindInfo->iStart, unless we find an item that match
	*/

	// Set the default return value to -1
	// That means we didn't find any match.
	*pResult = -1;

	//Is search NOT based on string?
	if( (pFindInfo->lvfi.flags & LVFI_STRING) == 0 )
	{
		//This will probably never happend...
		return;
	}

	/*
	Let's look on a sample list;

	Name
	Anders
	* Anna
	Annika
	Bob
	Emma
	Emmanuel

	Anna is selected. 
	If "A" is written, Annika should be selected.
	If "AND" is written, Anders should be selected. 
	If "ANNK" is written, the selection should stay on Anna.
	If "E" is written, Emma should be selected.

	*/

	//This is the string we search for
	CString searchstr = pFindInfo->lvfi.psz;

	//	TRACE(_T("Find: %s\n"), searchstr);

	int startPos = pFindInfo->iStart;
	//Is startPos outside the list (happens if last item is selected)
	// 	if(startPos >= m_list.GetItemCount())
	// 		startPos = 0;

	int currentPos=startPos;

	//Let's search...
	// 	do
	// 	{		
	// 		//Do this word begins with all characters in searchstr?
	// 		if( _tcsnicmp(m_database[currentPos].m_name, searchstr, searchstr.GetLength()) == 0)
	// 		{
	// 			//Select this item and stop search.
	// 			*pResult = currentPos;
	// 			break;
	// 		}
	// 
	// 		//Go to next item
	// 		currentPos++;
	// 
	// 		//Need to restart at top?
	// 		if(currentPos >= m_list.GetItemCount())
	// 			currentPos = 0;
	// 
	// 	//Stop if back to start
	// 	}while(currentPos != startPos);		
}

//虚表要实现的函数之三
//This is called to give you a chance to catch data. Useless in most cases :-)
void CNavigationDialog::OnOdcachehintList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NMLVCACHEHINT* pCacheHint = (NMLVCACHEHINT*)pNMHDR;

	/*	TRACE(	_T("Chache item %d to item %d\n"),
	pCacheHint->iFrom,
	pCacheHint->iTo );*/

	//... cache the data pCacheHint->iFrom to pCacheHint->iTo ...

	*pResult = 0;
}

d、填充数据

p_list_History->SetItemCountEx(vec_bjq_datas.size(),LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);

代码是我项目中的片段,具体根据实际修改。

参考:

https://www.cnblogs.com/lidabo/p/3410400.html

http://www.cppblog.com/woaidongmao/archive/2011/11/14/160088.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值