重载OnNotify消息响应函数,屏蔽两个消息通知码:HDN_BEGINTRACKW 和HDN_DIVIDERDBLCLICKW。示例如下: - BOOL CXXXX::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
- {
-
-
- NMHEADER* pNMHeader = (NMHEADER*)lParam;
- if(((pNMHeader->hdr.code == HDN_BEGINTRACKW) |
- (pNMHeader->hdr.code == HDN_DIVIDERDBLCLICKW)))
- {
- *pResult = TRUE;
- return TRUE;
- }
-
- return CDialog::OnNotify(wParam, lParam, pResult);
- }
2、虚拟列表技术
给一个链接,介绍的比较详细:http://hi.baidu.com/qi_xian/blog/item/929b04ce27d02c0592457ef8.html
当数据量大时,使用InsertItem插入数据的过程是很漫长的。这时我们有两个方法来解决该问题:一是使用CListCtrl的虚拟列表技术,二是采用分页显示的方法。对于虚拟列表技术,上述链接中的文章讲的很详细,我用过它的比较简单的方法,后来改用了分页方法。
使用虚拟列表技术,有三点需要搞清楚:
① 使用虚拟技术时,需要将CListCtrl控件的Owner Data属性设置为ture。
② 给虚拟列表添加元素时,不需要使用InserItem函数,通过调用SetItemCount设置数据总个数,然后由系统产生不同的消息,在相应的消息响应函数中完成插入工作。
③ 虚拟列表向父窗口发送的消息有三种: ⑴ 当它需要数据时,发送LVN_GETDISPINFO消息; ⑵ 当用户试图查找某个元素时,发送LVN_ODFINDITEM消息; ⑶当需要缓冲数据时,发送 LVN_ODCACHEHINT消息。
当我们使用LVN_GETDISPINFO 的消息处理函数来插入元素时,必须首先检查列表请求的是什么数据(如LVIF_TEXT、LVIF_IMAGE等),然后插入不同的子项。示例如下:
- void CDataAnalysis::OnLvnGetdispinfoAnalysisList(NMHDR *pNMHDR, LRESULT *pResult)
- {
- NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
-
- LV_ITEM* pItem= &(pDispInfo)->item;
- int iItemIndex= pItem->iItem;
- size_t converted = 0;
- wchar_t wStr[30];
- if (pItem->mask & LVIF_TEXT)
- {
- switch(pItem->iSubItem)
- {
- case 0:
- mbstowcs_s(&converted, wStr, 30, xxxxxx, _TRUNCATE);
- lstrcpy(pItem->pszText,wStr);
- break;
- case 1:
- mbstowcs_s(&converted, wStr, 30, xxxxxx, _TRUNCATE);
- lstrcpy(pItem->pszText,wStr);
- break;
- case 2:
- mbstowcs_s(&converted, wStr, 30, xxxxxx, _TRUNCATE);
- lstrcpy(pItem->pszText,wStr);
- break;
- case 3:
- lstrcpy(pItem->pszText,xxxxxx);
- break;
- }
- }
-
- *pResult = 0;
- }
3、点击表头时进行归类排序
系统通过发送LVM_SORTITEMS消息来处理归类问题,在该消息的处理函数中需要调用一个回调函数,这个回调函数需要我们来设计,以完成不同的归类方法。回调函数原型如下:
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
针对上述回调函数,有以下几点需要搞清楚:
① 对于参数lparam1和lparam2,分别为CListCtrl的两行数据,是用于比较的对象。通过CListCtrl的成员函数SetItemData来设置,该函数原型:
int SetItemData(int nIndex, DWORD_PTR dwItemData )
其第一个参数为行号,第二个参数指明了该行对应的参数。参数dwItemData 通常设为一行参数的数组,如: pData[2][2] = {{1, 3},{2, 3}}; 每次使用pData[i]作为dwItemData。
② 对于参数lParamSort,用于指明列项,即第几列。该参数和回调函数一同通过CListCtrl的成员函数SortItems来设置,其函数原型为:
BOOL SortItems( PFNLVCOMPARE pfnCompare,DWORD_PTR dwData )
参数 pfnCompare 为回调函数入口地址, 参数dwData 为列项。
③ SetItemData在初始插入数据时进行调用来设置,SortItems则在点击列表头时响应的消息处理函数中进行设置。
示例如下:
-
- BOOL CDataAnalysis::InitListCtl()
- {
-
-
- for(int i=0; i<LineNum; i++)
- {
-
- mbstowcs_s(&converted, wStr, 30, m_analysis[i].Date, _TRUNCATE);
- m_listAnalysis.InsertItem(i, wStr);
- mbstowcs_s(&converted, wStr, 30, m_analysis[i].Time, _TRUNCATE);
- m_listAnalysis.SetItemText(i, 1, wStr);
- mbstowcs_s(&converted, wStr, 30, m_analysis[i].ID, _TRUNCATE);
- m_listAnalysis.SetItemText(i, 2, wStr);
- m_listAnalysis.SetItemText(i, 3, m_analysis[i].lpszEvent);
-
-
- m_listAnalysis.SetItemData(i, (LPARAM)(m_analysis+i));
- }
-
- return TRUE;
- }
- void CDataAnalysis::OnHdnItemclickAnalysisList(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
-
-
-
- m_listAnalysis.SortItems(SortFunc, phdr->iItem);
-
- *pResult = 0;
- }
-
- int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
- {
- int result;
-
-
- ANALYSISFORMAT* pAnalysis1 = (ANALYSISFORMAT*)lParam1;
- ANALYSISFORMAT* pAnalysis2 = (ANALYSISFORMAT*)lParam2;
-
-
- switch(lParamSort)
- {
- case 0:
- result = strcmp(pAnalysis1->Date, pAnalysis2->Date);
- break;
- case 1:
- result = strcmp(pAnalysis1->Time, pAnalysis2->Time);
- break;
- case 2:
- result = strcmp(pAnalysis1->ID, pAnalysis2->ID);
- break;
- case 3:
- result = wcscmp(pAnalysis1->lpszEvent, pAnalysis2->lpszEvent);
- break;
- default:
- break;
- }
-
- return result;
- }