精华内容
参与话题
问答
  • CListCtrl

    2012-09-04 10:08:17
    CListCtrl使用技巧汇总 以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn //整理过程中加入自己实践过程...
    
    

    以下未经说明,listctrl默认view 风格为report

    相关类及处理函数

    MFC:CListCtrl类

    SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn

    //整理过程中加入自己实践过程的一些使用代码

     

    1. CListCtrl 风格

          LVS_ICON: 为每个item显示大图标
          LVS_SMALLICON: 为每个item显示小图标
          LVS_LIST: 显示一列带有小图标的item
          LVS_REPORT: 显示item详细资料

          直观的理解:windows资源管理器,“查看”标签下的“大图标,小图标,列表,详细资料”

    2. 设置listctrl 风格及扩展风格

          LONG lStyle;
          lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style
          lStyle &= ~LVS_TYPEMASK; //清除显示方式位
          lStyle |= LVS_REPORT; //设置style
          SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style
     
          DWORD dwStyle = m_list.GetExtendedStyle();
          dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
          dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
          dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
          m_list.SetExtendedStyle(dwStyle); //设置扩展风格
     
          注:listview的style请查阅msdn
          http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp

    3. 插入数据

          m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入列
          m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );
          int nRow = m_list.InsertItem(0, “11”);//插入行
          m_list.SetItemText(nRow, 1, “jacky”);//设置数据

    4. 一直选中item

        选中style中的Show selection always,或者在上面第2点中设置LVS_SHOWSELALWAYS

    5. 选中和取消选中一行

        int nIndex = 0;
        //选中
        m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
        //取消选中
        m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

    6. 得到listctrl中所有行的checkbox的状态

          m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
          CString str;
          for(int i=0; i      {
               if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
               {
                    str.Format(_T("第%d行的checkbox为选中状态"), i);
                    AfxMessageBox(str);
               }
          }

    7. 得到listctrl中所有选中行的序号


          方法一:
          CString str;
          for(int i=0; i      {
               if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
               {
                    str.Format(_T("选中了第%d行"), i);
                    AfxMessageBox(str);
               }
          }

          方法二:
          POSITION pos = m_list.GetFirstSelectedItemPosition();
          if (pos == NULL)
               TRACE0("No items were selected!\n");
          else
          {
               while (pos)
               {
                    int nItem = m_list.GetNextSelectedItem(pos);
                    TRACE1("Item %d was selected!\n", nItem);
                    // you could do your own processing on nItem here
               }
          }

    8. 得到item的信息

          TCHAR szBuf[1024];
          LVITEM lvi;
          lvi.iItem = nItemIndex;
          lvi.iSubItem = 0;
          lvi.mask = LVIF_TEXT;
          lvi.pszText = szBuf;
          lvi.cchTextMax = 1024;
          m_list.GetItem(&lvi);

          关于得到设置item的状态,还可以参考msdn文章
          Q173242: Use Masks to Set/Get Item States in CListCtrl
                   http://support.microsoft.com/kb/173242/en-us

    9. 得到listctrl的所有列的header字符串内容

          LVCOLUMN lvcol;
          char  str[256];
          int   nColNum;
          CString  strColumnName[4];//假如有4列

          nColNum = 0;
          lvcol.mask = LVCF_TEXT;
          lvcol.pszText = str;
          lvcol.cchTextMax = 256;
          while(m_list.GetColumn(nColNum, &lvcol))
          {
               strColumnName[nColNum] = lvcol.pszText;
               nColNum++;
          }

    10. 使listctrl中一项可见,即滚动滚动条

        m_list.EnsureVisible(i, FALSE);

    11. 得到listctrl列数

        int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();

    12. 删除所有列

          方法一:
             while ( m_list.DeleteColumn (0))
           因为你删除了第一列后,后面的列会依次向上移动。

          方法二:
          int nColumns = 4;
          for (int i=nColumns-1; i>=0; i--)
              m_list.DeleteColumn (i);

    13. 得到单击的listctrl的行列号

          添加listctrl控件的NM_CLICK消息相应函数
          void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
          {
               // 方法一:
               /*
               DWORD dwPos = GetMessagePos();
               CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
      
               m_list.ScreenToClient(&point);
      
               LVHITTESTINFO lvinfo;
               lvinfo.pt = point;
               lvinfo.flags = LVHT_ABOVE;
        
               int nItem = m_list.SubItemHitTest(&lvinfo);
               if(nItem != -1)
               {
                    CString strtemp;
                    strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
                    AfxMessageBox(strtemp);
               }
              */
      
              // 方法二:
              /*
               NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
               if(pNMListView->iItem != -1)
               {
                    CString strtemp;
                    strtemp.Format("单击的是第%d行第%d列",
                                    pNMListView->iItem, pNMListView->iSubItem);
                    AfxMessageBox(strtemp);
               }
              */
               *pResult = 0;
          }

    14. 判断是否点击在listctrl的checkbox上

          添加listctrl控件的NM_CLICK消息相应函数
          void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
          {
               DWORD dwPos = GetMessagePos();
               CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
      
               m_list.ScreenToClient(&point);
      
               LVHITTESTINFO lvinfo;
               lvinfo.pt = point;
               lvinfo.flags = LVHT_ABOVE;
        
               UINT nFlag;
               int nItem = m_list.HitTest(point, &nFlag);
               //判断是否点在checkbox上
               if(nFlag == LVHT_ONITEMSTATEICON)
               {
                    AfxMessageBox("点在listctrl的checkbox上");
               }
               *pResult = 0;
          } 


    15. 右键点击listctrl的item弹出菜单

          添加listctrl控件的NM_RCLICK消息相应函数
          void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
          {
               NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
               if(pNMListView->iItem != -1)
               {
                    DWORD dwPos = GetMessagePos();
                    CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
       
                    CMenu menu;
                    VERIFY( menu.LoadMenu( IDR_MENU1 ) );
                    CMenu* popup = menu.GetSubMenu(0);
                    ASSERT( popup != NULL );
                    popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
               }
               *pResult = 0;
      }


     

    16. item切换焦点时(包括用键盘和鼠标切换item时),状态的一些变化顺序

          添加listctrl控件的LVN_ITEMCHANGED消息相应函数
          void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
          {
               NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
               // TODO: Add your control notification handler code here
       
               CString sTemp;
     
               if((pNMListView->uOldState & LVIS_FOCUSED) == LVIS_FOCUSED &&
                (pNMListView->uNewState & LVIS_FOCUSED) == 0)
               {
                    sTemp.Format("%d losted focus",pNMListView->iItem);
               }
               else if((pNMListView->uOldState & LVIS_FOCUSED) == 0 &&
                   (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
               {
                    sTemp.Format("%d got focus",pNMListView->iItem);
               }
     
               if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED &&
                (pNMListView->uNewState & LVIS_SELECTED) == 0)
               {
                    sTemp.Format("%d losted selected",pNMListView->iItem);
               }
               else if((pNMListView->uOldState & LVIS_SELECTED) == 0 &&
                (pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED)
               {
                    sTemp.Format("%d got selected",pNMListView->iItem);
               }
       
               *pResult = 0;
          }



    17. 得到另一个进程里的listctrl控件的item内容

    http://www.codeproject.com/threads/int64_memsteal.asp


    18. 选中listview中的item

    Q131284: How To Select a Listview Item Programmatically
    http://support.microsoft.com/kb/131284/en-us


    19. 如何在CListView中使用CListCtrl的派生类

    http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/


    20. listctrl的subitem添加图标

          m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
          m_list.SetItem(..); //具体参数请参考msdn

     

    21. 在CListCtrl显示文件,并根据文件类型来显示图标

          网上找到的代码,share
          BOOL CTest6Dlg::OnInitDialog()
          {
               CDialog::OnInitDialog();
      
               HIMAGELIST himlSmall;
               HIMAGELIST himlLarge;
               SHFILEINFO sfi;
               char  cSysDir[MAX_PATH];
               CString  strBuf;
     
               memset(cSysDir, 0, MAX_PATH);
      
               GetWindowsDirectory(cSysDir, MAX_PATH);
               strBuf = cSysDir;
               sprintf(cSysDir, "%s", strBuf.Left(strBuf.Find("\\")+1));
     
               himlSmall = (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir, 
                          0, 
                          &sfi,
                          sizeof(SHFILEINFO), 
                          SHGFI_SYSICONINEX | SHGFI_SMALLICON );
      
               himlLarge = (HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir, 
                          0, 
                          &sfi, 
                          sizeof(SHFILEINFO), 
                          SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
      
               if (himlSmall && himlLarge)
               {
                    ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
                                 (WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);
                    ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
                                 (WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);
               }
               return TRUE;  // return TRUE  unless you set the focus to a control
          }
     
          void CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)
          {
               int nIcon = GetIconIndex(lpszFileName, FALSE, FALSE);
               CString strSize;
               CFileFind filefind;
     
               //  get file size
               if (filefind.FindFile(lpszFileName))
               {
                    filefind.FindNextFile();
                    strSize.Format("%d", filefind.GetLength());
               }
               else
                    strSize = "0";
      
               // split path and filename
               CString strFileName = lpszFileName;
               CString strPath;
     
               int nPos = strFileName.ReverseFind('\\');
               if (nPos != -1)
               {
                    strPath = strFileName.Left(nPos);
                    strFileName = strFileName.Mid(nPos + 1);
               }
      
               // insert to list
               int nItem = m_list.GetItemCount();
               m_list.InsertItem(nItem, strFileName, nIcon);
               m_list.SetItemText(nItem, 1, strSize);
               m_list.SetItemText(nItem, 2, strFileName.Right(3));
               m_list.SetItemText(nItem, 3, strPath);
          }
     
          int CTest6Dlg::GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected)
          {
               SHFILEINFO sfi;
               memset(&sfi, 0, sizeof(sfi));
      
               if (bIsDir)
               {
                SHGetFileInfo(lpszPath, 
                             FILE_ATTRIBUTE_DIRECTORY, 
                             &sfi, 
                             sizeof(sfi), 
                             SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
                             SHGFI_USEFILEATTRIBUTES |(bSelected ? SHGFI_OPENICON : 0)); 
                return  sfi.iIcon;
               }
               else
               {
                SHGetFileInfo (lpszPath, 
                             FILE_ATTRIBUTE_NORMAL, 
                             &sfi, 
                             sizeof(sfi), 
                             SHGFI_SMALLICON | SHGFI_SYSICONINDEX | 
                             SHGFI_USEFILEATTRIBUTES | (bSelected ? SHGFI_OPENICON : 0));
                return   sfi.iIcon;
               }
               return  -1;
          }


    22. listctrl内容进行大数据量更新时,避免闪烁

          m_list.SetRedraw(FALSE);
          //更新内容
          m_list.SetRedraw(TRUE);
          m_list.Invalidate();
          m_list.UpdateWindow();
     
    或者参考

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwnd.3a3a.setredraw.asp


    23. listctrl排序

    Q250614:How To Sort Items in a CListCtrl in Report View
    http://support.microsoft.com/kb/250614/en-us


    24. 在listctrl中选中某个item时动态改变其icon或bitmap

    Q141834: How to change the icon or the bitmap of a CListCtrl item in Visual C++
    http://support.microsoft.com/kb/141834/en-us


    25. 在添加item后,再InsertColumn()后导致整列数据移动的问题

    Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift
    http://support.microsoft.com/kb/151897/en-us


    26. 关于listctrl第一列始终居左的问题

    解决办法:把第一列当一个虚列,从第二列开始插入列及数据,最后删除第一列。
         
    具体解释参阅   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp

     

    27. 锁定column header的拖动

    http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/


    28. 如何隐藏clistctrl的列

        把需隐藏的列的宽度设为0,然后检测当该列为隐藏列时,用上面第27点的锁定column 的拖动来实现

    29. listctrl进行大数据量操作时,使用virtual list   

    http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/
    http://www.codeproject.com/listctrl/virtuallist.asp


    30. 关于item只能显示259个字符的问题

    解决办法:需要在item上放一个edit。


    31. 响应在listctrl的column header上的鼠标右键单击

    Q125694: How To Find Out Which Listview Column Was Right-Clicked
    http://support.microsoft.com/kb/125694/en-us


    32. 类似于windows资源管理器的listview

    Q234310: How to implement a ListView control that is similar to Windows Explorer by using DirLV.exe
    http://support.microsoft.com/kb/234310/en-us

     

    33. 在ListCtrl中OnTimer只响应两次的问题

    Q200054:
    PRB: OnTimer() Is Not Called Repeatedly for a List Control
    http://support.microsoft.com/kb/200054/en-us

    34. 以下为一些为实现各种自定义功能的listctrl派生类

              (1)    拖放       
                       http://www.codeproject.com/listctrl/dragtest.asp

                       在CListCtrl和CTreeCtrl间拖放
                       http://support.microsoft.com/kb/148738/en-us
     
              (2)    多功能listctrl
                       支持subitem可编辑,图标,radiobutton,checkbox,字符串改变颜色的类
                       http://www.codeproject.com/listctrl/quicklist.asp
     
                       支持排序,subitem可编辑,subitem图标,subitem改变颜色的类
                       http://www.codeproject.com/listctrl/ReportControl.asp

              (3)    subitem中显示超链接
                       http://www.codeproject.com/listctrl/CListCtrlLink.asp

              (4)    subitem的tooltip提示
                       http://www.codeproject.com/listctrl/ctooltiplistctrl.asp

              (5)    subitem中显示进度条   
                       http://www.codeproject.com/listctrl/ProgressListControl.asp
                       http://www.codeproject.com/listctrl/napster.asp
                       http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/

              (6)    动态改变subitem的颜色和背景色
                        http://www.codeproject.com/listctrl/highlightlistctrl.asp
                        http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/
     
              (7)    类vb属性对话框
                &bsp;       http://www.codeproject.com/listctrl/propertylistctrl.asp
                        http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/
                        http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/
     
              (8)    选中subitem(只高亮选中的item)
                        http://www.codeproject.com/listctrl/SubItemSel.asp
                        http://www.codeproject.com/listctrl/ListSubItSel.asp
     
              (9)    改变行高
                        http://www.codeproject.com/listctrl/changerowheight.asp
     
              (10)   改变行颜色
                        http://www.codeproject.com/listctrl/coloredlistctrl.asp
     
              (11)   可编辑subitem的listctrl
                        http://www.codeproject.com/listctrl/nirs2000.asp
                        http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp
     
              (12)   subitem可编辑,插入combobox,改变行颜色,subitem的tooltip提示
                        http://www.codeproject.com/listctrl/reusablelistcontrol.asp
     
              (13)   header 中允许多行字符串
                        http://www.codeproject.com/listctrl/headerctrlex.asp
     
              (14)   插入combobox
                        http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/
     
              (15)   添加背景图片
                        http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/
                        http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/
                        http://www.vchelp.net/vchelp/archive.asp?type_id=9&class_id=1&cata_id=1&article_id=1088&search_term=
       
              (16)  自适应宽度的listctrl
                        http://www.codeproject.com/useritems/AutosizeListCtrl.asp

              (17)  改变ListCtrl高亮时的颜色(默认为蓝色)
                       处理 NM_CUSTOMDRAW
              
    http://www.codeproject.com/listctrl/lvcustomdraw.asp

    //2009-05-06

    35.  隐藏滚动条

    void   CListView_ScrollBarView::OnSize(UINT   nType,   int   cx,   int   cy)    
      {  
      CListCtrl   &   ctrl   =   this->GetListCtrl   ();  
      if   (ctrl)  
      {  
                              //隐藏垂直滚动条  
              ::ShowScrollBar(   ctrl.m_hWnd,   SB_VERT,   FALSE);  
      }  
      CListView::OnSize(nType,   cx,   cy);  
      }

    //2009-05-07

    36. 处理键盘,循环滚动,不要在对话框中处理该消息,否则WListCtrlEx会产生两次按键事件

    BOOL WListCtrlEx::PreTranslateMessage(MSG* pMsg)
    {
     // TODO: Add your specialized code here and/or call the base class
     if (pMsg->message == WM_KEYDOWN)
     {
      if (pMsg->wParam == VK_DOWN)
      {
       int nSel = GetNextItem(-1, LVNI_SELECTED);
       if (nSel == -1)
        return FALSE;
       if (nSel == GetItemCount()-1)
       {
        EnsureVisible(0, FALSE);   //滚动条自动滚动到第80行  
        SetItemState(0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
        return TRUE;
       }
      }
      if (pMsg->wParam == VK_UP)
      {   
       int nSel = GetNextItem(-1, LVNI_SELECTED);
       if (nSel == -1)
        return FALSE;
       if (nSel == 0)
       {
        EnsureVisible(GetItemCount()-1, FALSE);   //滚动条自动滚动到第80行 
        SetItemState(GetItemCount()-1, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
        return TRUE;
       }
      }
     }
     
     return CListCtrl::PreTranslateMessage(pMsg);
    }

    展开全文
  • ClistCtrl

    千次阅读 2013-08-22 10:15:09
    1. 关于带 chexbox 和图像的 CListCtrl (1)设置具有chexbox风格的属性 //设置比较站风格、、、 LONG lCompareStyle; lCompareStyle = GetWindowLong(m_ComparePoc.m_hWnd, GWL_STYLE);//获取当前窗口style ...

    原文出处忘了

    1. 关于带 chexbox 和图像的 CListCtrl

    (1)设置具有chexbox风格的属性

    //设置比较站风格、、、
    LONG lCompareStyle;
    lCompareStyle = GetWindowLong(m_ComparePoc.m_hWnd, GWL_STYLE);//获取当前窗口style
    lCompareStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
    m_ComparePoc.SetExtendedStyle(lCompareStyle); //设置扩展风格
    


    其中的m_ComparePoc是view为SmalIcon的clistCtrl对象。
    (2)添加图像

    m_imageList.Create(16, 16, ILC_COLOR16|ILC_MASK, 1, 1);
    m_imageList.Add(AfxGetApp()->LoadIcon(IDI_ICON_POC));
    m_ComparePoc.SetImageList(&m_imageList,LVSIL_SMALL);
    


    其中的m_imageList为CImageList的对象IDI_ICON_POC为资源中的一个ICON的ID。
    (3)检查是否被选择

    m_ComparePoc.GetCheck(i)
    


    如果被选择则会返回真,否则为假。
    (4)选择
    m_ComparePoc.GetCheck(i)

    m_ComparePoc.GetCheck(i)
    


    置为选择状态,如果是选择的话,此函数也不会出错。

     


    2. 关于 reportreport 的 clistCtrl

    第三方控件的CReportCtrl类。
    (1)设置风格的属性
    //设置比较内容显示风格、、、
    LONG lCompareShowStyle;
    lCompareShowStyle = GetWindowLong(m_CompareShow.m_hWnd, GWL_STYLE);//获取当前窗口style
    lCompareShowStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
    lCompareShowStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
    m_CompareShow.SetExtendedStyle(lCompareShowStyle); //设置扩展风格
    


    (2)单元格背景色设置

    m_CompareShow.SetItemBkColor(j,i+1,RGB(255,0,0), FALSE); 
    
    


    其中的j和i+1和CListCtrl一样,都是从零开始的,FALSE表示不刷新整个控件,否则刷新整个控件。
    (3)删除所有列

     m_CompareShow.DeleteAllColumns();
    


    其中只是删除表头。
    (4)删除所有的行 

     m_CompareShow.CListCtrl::DeleteAllItems();
    


    这里调用CListCtrl的DeleteAllItems函数,而不是CReportCtrl里重载的DeleteAllItems函数
    因为此函数会造成整个对话框的刷新和屏幕背景的刷新(原因未知,具体可查看源码)

    CReportCtrl类http://download.csdn.net/detail/wuyuan2011woaini/5991311

    展开全文
  • CLISTCTRL

    2019-09-24 21:23:44
     定义一个CListCtrl控件的关联变量ListControl,在OnInitDialog()函数里面加上如下代码 1 ////初始化界面 2 ListControl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); 3 LONG lStyle; 4 ....

    1.添加表头:

      定义一个CListCtrl控件的关联变量ListControl,在OnInitDialog()函数里面加上如下代码

    复制代码
     1     初始化界面
     2     ListControl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
     3     LONG lStyle;
     4     lStyle = GetWindowLong(ListControl.m_hWnd, GWL_STYLE);//获取当前窗口style
     5     lStyle &= ~LVS_TYPEMASK; //清除显示方式位
     6     lStyle |= LVS_REPORT; //设置style
     7     SetWindowLong(ListControl.m_hWnd, GWL_STYLE, lStyle);//设置style
     8 
     9     //添加列
    10     ListControl.InsertColumn( 0, _T("映像名称"),LVCFMT_CENTER, 150);//插入列
    11     ListControl.InsertColumn(1,_T("PID"),LVCFMT_CENTER,50);        
    12     ListControl.InsertColumn(2,_T("优先级"),LVCFMT_CENTER,100);    
    13     ListControl.InsertColumn(3,_T("线程数"),LVCFMT_CENTER, 50);
    复制代码

     

    2.插入信息:

    复制代码
    1         void InsertData()
    2         {
    3             int nCount = ListControl.GetItemCount();//获取当前已插入的行数
    4             ListControl.InsertItem(nCount, _T(""));//插入一行
    5             ListControl.SetItemText(nCount, 0, iterBegin->second.strExeFile);//第一列
    6             ListControl.SetItemText(nCount, 1, iterBegin->second.strPID);//第二列
    7             ListControl.SetItemText(nCount, 2, iterBegin->second.strPriority);//第三列
    8             ListControl.SetItemText(nCount, 3, iterBegin->second.strThreadCount);//第四列
    9         }
    复制代码

    3.获取当前选中的项:

    方法1:

        POSITION p = ListControl.GetFirstSelectedItemPosition();//获取当前选中的行的第一行的位置
    //获取选中的第一行的行索引
    int nIndex = ListControl.GetNextSelectedItem(p);//可能多选,GetNextSelectedItem使p移动一个位置 //得到第index行.第2列的内容(下标从0开始) CString strColumn = ListControl.GetItemText(nIndex,1);

    方法2:

    1     int nIndex=ListControl.GetSelectionMark();//获取选中的行
    2     CString strPID =ListControl.GetItemText(nIndex, 1); //选中的行、列的值

     

     

    4.获取选中的行和列

    1 void CMFC_TestDlg::OnNMClickList2(NMHDR *pNMHDR, LRESULT *pResult)
    2 {
    3     LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    4     m_nSelectColumn = pNMLV->iSubItem;//获取选中的行
    5     m_nSelectLine = ListControl.GetSelectionMark();//获取选中的列
    6 }

     

    5.右键添加菜单

      添加NM_RCLICK消息,消息响应代码如下:

    复制代码
     1 void CMFC_TestDlg::OnNMRClickList2(NMHDR *pNMHDR, LRESULT *pResult)
     2 {
     3     CMenu menu ,* pSubMenu; //定义下面要用到的cmenu对象 
    4 menu.LoadMenu(IDR_POPMENU); //装载自定义的右键菜单 IDR_POPMENU弹出菜单的ID
    5 6 //获取第一个弹出菜单,所以第一个菜单必须有子菜单
    7 pSubMenu = menu.GetSubMenu(0);

    8 9 CPoint oPoint; //定义一个用于确定光标位置的位置
    10 GetCursorPos( &oPoint); //获取当前光标的位置,以便使得菜单可以跟随光标11 12 pSubMenu->TrackPopupMenu (TPM_LEFTALIGN, oPoint.x, oPoint.y, this); //显示菜单,第四个为传递的参数 13 *pResult = 0;
        //pSubMenu->EnableMenuItem(ID_EDIT_PASTE, MF_DISABLED | MF_GRAYED)禁用菜单的某项
    14 }
    复制代码

     

    6.列排序

      

    复制代码
     1 BOOL g_bSort;//全局变量,用于标识是按从大到小还是从小到大排序
     2 
     3 typedef struct
     4 {
     5     CListCtrl *plist;//存储当前的ListCtrl指针
     6     int col;//存储当前选中的列
     7 } SortList;
     8 
     9 
    10 //添加LVNCOLUMNCLICK消息
    11 void CMFC_TestDlg::OnLvnColumnclickList2(NMHDR *pNMHDR, LRESULT *pResult) 12 { 13 LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); 14 15 g_bSort = !g_bSort;//每次点击后取反 16 for(int i = 0; i < ListControl.GetItemCount(); ++i) 17 ListControl.SetItemData(i,i); //这个是必须的 18 19 //用SortList存储当前的CListCtrl和选中的列 20 SortList listData; 21 listData.plist = &ListControl; 22 listData.col = pNMLV->iSubItem; 23 24 //排序,第一个参数为全局排序函数(它就是回调函数)的地址,第二个参数为传递的数据,
    25 ListControl.SortItems(MylistCompare, (LPARAM)&listData); 26 *pResult = 0; 27 }
    复制代码

     

    排序函数:

     该函数返回-1,代表第一项排应在第二项前面;
     返回1代表第一项排应在第二项后面;
     返回0代表两项相等。

    复制代码
    int CALLBACK MylistCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) 
    
    {
        SortList * listData = (SortList*)lParamSort;//获取传入的参数
        CListCtrl*   pListCtrl  =  listData->plist; 
    
        CString  strItem1;
        CString  strItem2;
        strItem1   =   pListCtrl->GetItemText(lParam1, listData->col);  
        strItem2   =   pListCtrl->GetItemText(lParam2, listData->col); 
    
        USES_CONVERSION;
        char *   s1=T2A(strItem1);  //转换为CString为char *
        char *   s2=T2A(strItem2); 
    
        int nResult = 0;
        switch(listData->col)//根据选择的列的数据类型进行自定义排序
        {
    //整形的排序
        case 1:
        case 3:
            {
                int   n1 = atoi(s1);  
                int   n2 = atoi(s2);  
    
                if   ( n1 >= n2)  
                {
                    nResult = 1;  
                }
    
                else    
                    nResult = -1;  
            }
            break;
    
    //字符串的排序
        case 0:
        case 2:
            {
                for (int i = 0; i<strlen(s1); i++)
                {
                    s1[i] = tolower(s1[i]); 
                    s2[i] = tolower(s2[i]); 
                }
    
                int nCompare = strcmp(s1, s2);
                if (nCompare >= 0)
                {
                    nResult = 1;
                }
                else
                    nResult = -1;
    
            }
            break;
        }
    
    //根据全局变量的值改变排序方法
        if (g_bSort)
        {
            return nResult;
        }
        else
        {
            return -nResult;
        }
    }
    复制代码

     

    7.全选(CTRL+A)

    复制代码
     1 BOOL CMFC_TestDlg::PreTranslateMessage(MSG* pMsg)
     2 {
     3     if (pMsg->message == WM_KEYDOWN)
     4     {
     5         if(pMsg->wParam == 'A')
     6         {
     7             if (::GetKeyState(VK_CONTROL)<0)
     8             {
     9                 for (int i = 0; i<ListControl.GetItemCount(); i++)
    10                 {
    11                     ListControl.SetItemState(i,LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
    12                 }
    13             }
    14         }
    15     }
    16     return FALSE;
    17 }
    复制代码

     

    8.修改列的新名称

    1     LVCOLUMN Column;
    2     ListControl.GetColumn(0,&Column);
    3     Column.pszText=L"0列新名称";
    4     ListControl.SetColumn(0,&Column);

     

    9.可编辑状态

    (1)设置EDIT Labels的属性为TRUE

    (2)添加事件NM_DBCLICK事件

    复制代码
     1     *pResult = 0;
     2 
     3     //双击事件产生edit控件,EditLabel会先确定list是否setFocus
     4     POSITION pos = ListControl.GetFirstSelectedItemPosition();
     5     int tIndex = ListControl.GetNextSelectedItem(pos);
     6 
     7     if ( tIndex >= 0 )
     8     {
     9         ListControl.SetFocus();
    10         CEdit* pEdit =ListControl.EditLabel( tIndex );
    11     }
    复制代码

     

    (3)添加事件LVN_ENDLABELEDIT事件

    复制代码
     1     NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
     2     // TODO: 在此添加控件通知处理程序代码
     3     *pResult = 0;
     4 
     5     CString pName = pDispInfo->item.pszText;
     6     int tIndex = pDispInfo->item.iItem;
     7     ListControl.SetFocus();
     8 
     9     if( ( ! pName.IsEmpty() ) && tIndex >= 0 )
    10     {
    11         ListControl.SetItemText( tIndex, 0, pName);
    12     }
    复制代码

     

    10.添加图标:

    (1)声明:

    1     //首先声明一个类的变量    
    2     CImageList m_imageList;
    3     //设置ListCtrl的图像列表
    4     m_imageList.Create(32,32, TRUE|ILC_COLOR32, 8, 8);
    5     m_listCtrl.SetImageList(&m_imageList, LVSIL_SMALL);

    (2)获取图标:

    1 SHFILEINFO   sfi = {0};
    2     SHGetFileInfo("d:\\a.txt",0,&sfi,sizeof(SHFILEINFO),SHGFI_ICON);
    3     m_imageList.Add(sfi.hIcon);

     

    (3)添加项:

    复制代码
    1     LVITEM lvItem;
    2     lvItem.iItem = m_listCtrl.GetItemCount();
    3     lvItem.iSubItem = 0;
    4     lvItem.iImage =m_imageList.GetImageCount()-1;//取最后一个
    5     lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
    6     lvItem.pszText = _T("TEST");    
    7 m_listCtrl.InsertItem(&lvItem);
    复制代码

     

    11.样式设置:

    (1).

      首先区分LVS_与LVS_EX_,哪些是常规样式,哪些是扩展样式:能在属性对话框里看到的样式都是常规样式,例如LVS_REPORT。

    扩展样式:

    LVS_EX_CHECKBOXES 您可以获得 ListView_GetCheckState 指定项目的复选框的状态。若要设置检查状态,请使用 ListView_SetCheckState。如果设置了此样式,则当用户单击该复选框,或按空格键在列表视图控件自动切换复选状态。
    LVS_EX_FLATSB 扁平滚动条 
    列表视图中的启用平面滚动条。如果您需要更多的控制列表视图滚动条的外观,您应该操作平的滚动栏 Api 使用直接的列表视图滚动条。如果更改系统度量,您负责调整与 FlatSB_SetScrollProp 的滚动栏度量。有关进一步的详细信息请参阅平滚动条。
    LVS_EX_FULLROWSELECT 选择整行 
    当选择某个项目时,强调了项目和其所有子项。此样式是仅在 LVS_REPORT 风格结合中可用。
    LVS_EX_GRIDLINES 绘制表格 
    显示项及其子项周围的网格线。此样式是仅在 LVS_REPORT 风格结合中可用
    LVS_EX_HEADERDRAGDROP 报表头可以拖拽 
    允许拖放的列表视图控件中的列重新排序。此样式是只可用于使用 LVS_REPORT 样式的列表视图控件。
    LVS_EX_INFOTIP 将提示信息窗口的消息通知父窗口 
    当列表视图控件使用的 LVS_EX_INFOTIP 样式时,LVN_GETINFOTIP 通知代码发送到父窗口显示工具提示项之前。
    LVS_EX_LABELTIP  
    LVS_EX_MULTIWORKAREAS 多工作区
    LVS_EX_ONECLICKACTIVATE 单击激活
    LVS_EX_REGIONAL  
    LVS_EX_SUBITEMIMAGES 子项目图标列表
    LVS_EX_TRACKSELECT 自动换行
    LVS_EX_TWOCLICKACTIVATE 双击激活
    LVS_EX_UNDERLINECOLD  
    LVS_EX_UNDERLINEHOT

     

    (2).

       下面弄清楚怎么设置常规样式和扩展样式。

       设置常规样式使用的函数:GetWindowLong(仅32位下)、SetWindowLong()

       设置扩展样式使用的函数:GetExtendedStyle、SetExtendedStyle

       示例代码:

    1   DWORD dwStyle=GetWindowLong(m_list.m_hWnd,GWL_STYLE);  
    2   SetWindowLong(m_list.m_hWnd,GWL_STYLE,dwStyle|LVS_REPORT);  
    3 
    4    DWORD styles=m_list.GetExtendedStyle();  
    5 
    6    m_list.SetExtendedStyle(styles|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);  

    转载于:https://www.cnblogs.com/xzh1993/p/6061644.html

    展开全文
  • clistctrl

    2014-10-30 16:16:27
    CListCtrl来显示数据比较方便,有时候我们需要标注某一列或某一个单元格的背景和字体颜色,或者需要改变一下行高和字体大小,CListCtrl要改变这些并不是很方便。本文将介绍如何派生一个类来改变CListCtrl及其表头...

    用CListCtrl来显示数据比较方便,有时候我们需要标注某一列或某一个单元格的背景和字体颜色,或者需要改变一下行高和字体大小,CListCtrl要改变这些并不是很方便。本文将介绍如何派生一个类来改变CListCtrl及其表头的高度、字体大小、列背景颜色、单元格背景颜色、列字体颜色、单元格字体颜色。


    一、 实现过程

    1.表头修改

    新建一个MFC类CHeaderCtrlCl,其基类为CHeaderCtrl,响应OnPaint消息实现自绘,实现代码请看源代码(由于代码较占篇幅,所以就不贴上来了,抱歉),在头文件中定义函数LRESULT OnLayout( WPARAM wParam, LPARAM lParam ),之后手动添加消息响应ON_MESSAGE(HDM_LAYOUT, OnLayout),在消息响应中改变高度,实现代码如下:

    1. LRESULT CHeaderCtrlCl::OnLayout( WPARAM wParam, LPARAM lParam )  
    2. {  
    3.     LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);   
    4.     HD_LAYOUT &hdl = *( HD_LAYOUT * ) lParam;   
    5.     RECT *prc = hdl.prc;   
    6.     WINDOWPOS *pwpos = hdl.pwpos;   
    7.   
    8.     //表头高度为原来1.5倍,如果要动态修改表头高度的话,将1.5设成一个全局变量   
    9.     int nHeight = (int)(pwpos->cy * m_Height);  
    10.     pwpos->cy = nHeight;   
    11.     prc->top = nHeight;   
    12.     return lResult;   
    13. }  

    2. 表的修改

    新建一个MFC类CListCtrlCl,其基类为CListCtrl,定义一个CHeaderCtrlCl的成员变量m_Header,重载PreSubclassWindow(),在函数中修改控件类型为自绘模式,然后子类化表头,代码如下:

    1. void CListCtrlCl::PreSubclassWindow()  
    2. {  
    3.     // TODO: 在此添加专用代码和/或调用基类  
    4.     ModifyStyle(0,LVS_OWNERDRAWFIXED);  
    5.     CListCtrl::PreSubclassWindow();  
    6.     CHeaderCtrl *pHeader = GetHeaderCtrl();  
    7.     m_Header.SubclassWindow(pHeader->GetSafeHwnd());  
    8. }  

    添加成员变量,保存一些基本信息。

    1.CPtrList m_ptrListCol; //保存列颜色
    2.CPtrList m_ptrListItem;//保存Item颜色表
    3.CPtrList m_colTextColor;//保存列字体颜色
    4.CPtrList m_ItemTextColor;//保存单元格字体颜色

    重载DrawItem()实现自绘,实现代码请参照代码。 手动添加消息宏ON_WM_MEASUREITEM_REFLECT(),添加下面的函数,实现修改行高。

    1. void CListCtrlCl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)  
    2. {  
    3.     if (m_nRowHeight>0)  
    4.     {  
    5.         lpMeasureItemStruct->itemHeight = m_nRowHeight;  
    6.     }  
    7. }  

    添加消息处理OnMeasureItem()

    1. void CListCtrlCl::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)  
    2. {  
    3.     // TODO: 在此添加消息处理程序代码和/或调用默认值  
    4.   
    5.     CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);  
    6. }  

    覆盖基类InsertColumn进行列信息保存

    1. int CListCtrlCl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat /* = LVCFMT_LEFT */int nWidth /* = -1 */int nSubItem /* = -1 */)  
    2. {  
    3.     m_Header.m_HChar.Add(lpszColumnHeading);  
    4.     if (nFormat==LVCFMT_LEFT)  
    5.     {  
    6.         m_Header.m_Format = m_Header.m_Format + "0";  
    7.     }  
    8.     else if (nFormat==LVCFMT_CENTER)  
    9.     {  
    10.         m_Header.m_Format = m_Header.m_Format + "1";  
    11.     }  
    12.     else if (nFormat==LVCFMT_RIGHT)  
    13.     {  
    14.         m_Header.m_Format = m_Header.m_Format + "2";  
    15.     }  
    16.     else  
    17.     {  
    18.         m_Header.m_Format = m_Header.m_Format + "1";  
    19.     }  
    20.     return CListCtrl::InsertColumn(nCol,lpszColumnHeading,nFormat,nWidth,nSubItem);  
    21. }  


    二、运行效果图如下:

    三、使用方法

    把HeaderCtrlCl.h, HeaderCtrlCl.cpp, ListCtrlCl.h, ListCtrlCl.cpp添加到你的工程中,在拖一个CListCtrl控件到对话框上,添加成员变量,然后在头文件中#include “ListCtrlCl.h”,把刚添加的成员变量类型改为 CListCtrlCl ,在对话框的OnInitDialog()中添加初始化代码:

    01.m_ListCtrl.SetColColor(0,RGB(10,150,20));//设置列背景色
    02.m_ListCtrl.SetColColor(2,RGB(30,100,90));//设置列背景色
    03.m_ListCtrl.SetBkColor(RGB(50,10,10));       //设置背景色
    04.m_ListCtrl.SetItemColor(1,1,RGB(100,100,10));//设置指定单元背景色
    05.m_ListCtrl.SetRowHeigt(25);              //设置行高度
    06.m_ListCtrl.SetHeaderHeight(1.5);         //设置头部高度
    07.m_ListCtrl.SetHeaderFontHW(16,0);  //设置头部字体高度,和宽度,0表示缺省,自适应
    08.m_ListCtrl.SetHeaderTextColor(RGB(255,200,100));//设置头部字体颜色
    09.m_ListCtrl.SetTextColor(RGB(0,255,255)); //设置文本颜色
    10.m_ListCtrl.SetHeaderBKColor(100,255,100,8);//设置头部背景色
    11.m_ListCtrl.SetFontHW(15,0);              //设置字体高度,和宽度,0表示缺省宽度
    12.m_ListCtrl.SetColTextColor(2,RGB(255,255,100));//设置列文本颜色
    13.m_ListCtrl.SetItemTextColor(3,1,RGB(255,0,0)); //设置单元格字体颜色

    四、结语

    本文仅介绍了一些主要的修改地方,详细请看源代码。对于修改类的不足和错误的地方请批评指正,本人十分感激。

    Email:qvb20974151@163.com

    源码地址:http://download.csdn.net/detail/qing666888/7970795

    展开全文

空空如也

1 2 3 4 5 ... 20
收藏数 4,044
精华内容 1,617
关键字:

clistctrl