CListCtrl 虚拟列表实现

18 篇文章 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
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

小新110

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值