1 2 3 CListView中内置了CListCtrl,所以对CListView的操作实际上就是对内置CListCtrl的操作。下面就从新建一个CListView的子类开始,我从工程中新建了一个叫做CInfoView的类,基类选择CListView。 4 5 1>----------初始化CListView,设置风格,背景和字体颜色,初始化行列。该项工作在OnInitialUpdate()中完成,如下所示。 6 7 void CInfoView::OnInitialUpdate() 8 { 9 CListView::OnInitialUpdate(); 10 // TODO: Add your specialized code here and/or call the base class 11 CListCtrl& m_list = GetListCtrl();//得到内置的listctrl引用 12 LONG lStyle; 13 lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口风格 14 lStyle &= ~LVS_TYPEMASK; //清除显示方式位 15 lStyle |= LVS_REPORT; //设置报表风格 16 SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle); //设置窗口风格 17 18 DWORD dwStyle = m_list.GetExtendedStyle(); 19 20 //选中某行使整行高亮(只适用于报表风格的listctrl) 21 dwStyle |= LVS_EX_FULLROWSELECT; 22 dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与报表风格的listctrl) 23 24 m_list.SetExtendedStyle(dwStyle); //设置扩展风格 25 m_list.SetBkColor(RGB(200, 200, 200)); //设置背景颜色 26 m_list.SetTextBkColor(RGB(200, 200, 200)); //设置文本背景颜色 27 m_list.SetTextColor(RGB(10, 10, 80)); //设置文本颜色 28 29 //插入列的标题,为了简单起见,我只插入三列 30 m_list.InsertColumn( 0, "图像帧号", LVCFMT_CENTER, 80 ); 31 m_list.InsertColumn( 1, "可见性判断", LVCFMT_CENTER, 110 ); 32 m_list.InsertColumn( 2, "置信度结果", LVCFMT_CENTER, 110 ); 33 } 34 35 36 2>----------插入一行数据。一般在实际应用中,都是在程序运行中,插入一行数据,这时候,需要在当前的程序语境中得到CInfoView的指针,然后进行插入数据的操作。在我的应用中,我把CinfoView作为拆分窗口的一个子窗口,所以具体操作如下: 37 38 CListView*listview=(CListView*)(((CMainFrame*)theApp.GetMainWnd())->m_wndSplitter1.GetPane(1,0));//得到ListView的指针 39 CListCtrl& list = listview->GetListCtrl();//得到listview内置listctrl的引用 40 CString strId, strCo;//图像帧号,置信度 41 CString strVb = "Y"; //可见性 42 if(fConfid[nIndex] <= 0) 43 { 44 strVb = "N"; 45 } 46 strId.Format("%d", nIndex+1); 47 strCo.Format("%.4f", fConfid[nIndex]); 48 49 //插入一行数据,始终在顶端插入新的数据 50 int nRow = list.InsertItem(0, strId); 51 list.SetItemText(nRow, 1, strVb); 52 list.SetItemText(nRow, 2, strCo); 53 54 3>----------右键单击弹出浮动菜单。在我的应用中,右键弹出的浮动菜单,只有一项:“删除所有内容”。要弹出浮动菜单,首先先要在“资源”的“Menu”中新建一个Menu,ID命名为IDR_POPMENU,然后在该Menu中添加一个主菜单“操作”,在“操作”下添加一个子菜单“删除所有内容”,ID命名为“ID_DELETE_ALL”,通过向导在CInfoView中给ID_DELETE_ALL添加消息响应函数OnDeleteAll(),如下: 55 56 void CInfoView::OnDeleteAll() 57 { 58 CListCtrl &m_list = GetListCtrl(); 59 m_list.DeleteAllItems(); 60 } 61 62 然后通过向导在CInfoView中添加右键单击响应函数=NM_RCLICK,如下: 63 64 void CInfoView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 65 { 66 // TODO: Add your control notification handler code here 67 CListCtrl &m_list = GetListCtrl(); //获取当前列表控件的指针 68 CMenu menu, *pSubMenu; //定义下面要用到的cmenu对象 69 menu.LoadMenu(IDR_POPMENU); //装载自定义的右键菜单 70 pSubMenu = menu.GetSubMenu(0); //获取第一个弹出菜单 71 CPoint oPoint; //定义一个用于确定光标位置的位置 72 GetCursorPos(&oPoint); //获取当前光标的位置 73 74 //在指定位置显示弹出菜单 75 pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, oPoint.x, oPoint.y, this); 76 } 77 78 4>----------添加消息响应函数OnCustomDraw(),为ClistCtrl的每个Item设置不同的颜色,在该应用中,为单数和偶数的Item项设置两种不同的颜色。具体步骤如下: 79 首先在InfoView.h的AFX_MSG之间添加消息函数声明: 80 afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); 81 然后在InfoView.cpp的BEGIN_MESSAGE_MAP之间添加消息映射: 82 ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) 83 最后在InfoView.cpp中添加函数实现: 84 85 void CInfoView::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) 86 { 87 LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR; 88 89 switch(lplvcd->nmcd.dwDrawStage) 90 { 91 int iRow; 92 case CDDS_PREPAINT: 93 *pResult = CDRF_NOTIFYITEMDRAW; 94 break; 95 case CDDS_ITEMPREPAINT: 96 *pResult = CDRF_DODEFAULT; 97 iRow= lplvcd->nmcd.dwItemSpec; 98 if(iRow & 1) 99 { 100 lplvcd->clrTextBk = RGB(230, 230, 230); 101 //lplvcd->clrText = RGB(255, 255, 0); 102 *pResult = CDRF_NEWFONT; 103 } 104 break; 105 default: 106 *pResult = CDRF_DODEFAULT; 107 } 108 } 109 110 5>----------为CInfoView添加点击列的标题进行排序的消息响应函数,在添加该消息响应函数之前,先要定义实现排序的回调函数。在该应用中,第一列是图像帧号,按自然数排序,其他列都按字串进行排列,所以定义两个比较的回调函数。 111 在InfoView.h中声明两个静态的回调函数: 112 113 static int CALLBACK ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);//按字串排序 114 115 static int CALLBACK ListViewCompareIntFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);//按自然数排序 116 117 在InfoView.cpp中实现两个静态的回调函数: 118 119 int CALLBACK CInfoView::ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) 120 { 121 // 得到排序方式 122 int *pisortorder = (int *)lParamSort; 123 124 // 得到两个列的排序信息 125 TCHAR *sz1 = (TCHAR *)lParam1; 126 TCHAR *sz2 = (TCHAR *)lParam2; 127 // 比较列的信息并返回比较结果。 128 // 若为减序,则将比较结果乘上-1。 129 if (*pisortorder == LVS_SORTASCENDING) 130 return lstrcmp(sz1, sz2); 131 else 132 return lstrcmp(sz1, sz2) * (-1); 133 } 134 135 int CALLBACK CInfoView::ListViewCompareIntFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) 136 { 137 // 得到排序方式 138 int *pisortorder = (int *)lParamSort; 139 // 得到两个列的排序信息 140 TCHAR *sz1 = (TCHAR *)lParam1; 141 TCHAR *sz2 = (TCHAR *)lParam2; 142 int n1 = _ttoi(sz1); 143 int n2 = _ttoi(sz2); 144 // 比较列的信息并返回比较结果。 145 // 若为减序,则将比较结果乘上-1。 146 if(*pisortorder == LVS_SORTASCENDING) 147 { 148 if(n1 - n2 > 0) return 1; 149 else if(n1 -n2 == 0) return 0; 150 else return -1; 151 } 152 else 153 { 154 if(n1 - n2 > 0) return -1; 155 else if(n1 -n2 == 0) return 0; 156 else return 1; 157 } 158 } 159 160 //然后通过向导为事件LVN_COLUMNCLICK添加消息响应函数OnColumnclick(),在该函数中调用上面的回调函数 161 void CInfoView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 162 { 163 // TODO: Add your control notification handler code here 164 static int ncurSortCol = -1; // 保存当前的排序列。 165 // 一开始表示为-1,表示尚未按任何列排序。 166 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 167 CListCtrl* lc = &GetListCtrl(); 168 LONG ws = GetWindowLong(lc->m_hWnd, GWL_STYLE); 169 int nSortOrder; // 排序的方式 170 171 // 若点击列与当前排序列不同的列,则改变排序序,并将排序方式改为增序。 172 // 若当前排序列与点击列相同,则更改增、减序的排序方式 173 if (ncurSortCol == pNMListView->iSubItem) 174 { 175 if (ws & LVS_SORTASCENDING) 176 { 177 ws ^= LVS_SORTASCENDING; 178 nSortOrder = LVS_SORTDESCENDING; 179 } 180 else 181 { 182 ws ^= LVS_SORTDESCENDING; 183 nSortOrder = LVS_SORTASCENDING; 184 } 185 } 186 else 187 { 188 if (ws & LVS_SORTASCENDING) 189 { 190 nSortOrder = LVS_SORTDESCENDING; 191 ncurSortCol = pNMListView->iSubItem; 192 } 193 else 194 { 195 nSortOrder = LVS_SORTASCENDING; 196 ncurSortCol = pNMListView->iSubItem; 197 } 198 } 199 200 // 将当前的排序信息保存在窗口Style中,供以后使用 201 ws |= nSortOrder; 202 SetWindowLong(lc->m_hWnd, GWL_STYLE, ws); 203 204 // 将各ITEM的LPARAM用新排序列的内容替换 205 LVITEM li; 206 li.mask = LVIF_PARAM|LVIF_TEXT; 207 TCHAR szItemText[1024]; 208 for (int i = 0; i < lc->GetItemCount(); i++) 209 { 210 li.iItem = i; 211 li.iSubItem = ncurSortCol; 212 li.cchTextMax = 1024; 213 li.pszText = szItemText; 214 lc->GetItem(&li); 215 TCHAR * szlparam = (TCHAR *)li.lParam; 216 // 删除以前的信息,释放空间 217 // 添加List Item时应注意将lParam初始化NULL 218 if (szlparam != NULL) 219 delete szlparam; 220 221 // 复制当前列的szItemText到Item的lParam中 222 szlparam = new TCHAR[lstrlen(szItemText) + 1]; 223 lstrcpy(szlparam, szItemText); 224 lc->SetItemData(i, DWORD(szlparam)); 225 } 226 227 // 开始排序 228 if(ncurSortCol == 0)//第一列按整数排序 229 { 230 GetListCtrl().SortItems(ListViewCompareIntFunc,(LPARAM)(&nSortOrder)); 231 } 232 else 233 GetListCtrl().SortItems(ListViewCompareFunc,(LPARAM)(&nSortOrder)); 234 *pResult = 0; 235 236 } 237 |
|
来自: zhaopengxslc > 《编程经验》