• (转)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(200200200));     //设置背景颜色
     26     m_list.SetTextBkColor(RGB(200200200)); //设置文本背景颜色
     27     m_list.SetTextColor(RGB(101080));      //设置文本颜色
     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(230230230);
    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 > 0return 1;
    149         else if(n1 -n2 == 0return 0;
    150         else return -1;
    151     }
    152     else
    153     {
    154         if(n1 - n2 > 0return -1;
    155         else if(n1 -n2 == 0return 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 
     
  • 相关阅读:
    .NET 4.5 is an in-place replacement for .NET 4.0
    python Argparse模块的使用
    linux的fork(), vfork()区别
    Linux 的 strace 命令
    NTFS系统的ADS交换数据流
    Git和.gitignore
    GIT常用命令
    OSChina码云试用
    tcpdump用法
    linux网卡混杂模式
  • 原文地址:https://www.cnblogs.com/wolfplan/p/1734281.html
Copyright © 2020-2023  润新知