CListView常用用法

CListView常用用法
代码
  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 

 

 

你可能感兴趣的:(ListView)