CListCtrl控件常用技巧

代码
由于CListCtrl良好的数据展示形式和便捷的操作,所以我们在编程工作中会经常用到,网上找到一片不错的总结,估计对于一般的使用场景够用的。还有其他需求,我们可以再探索讨论。

以下未经说明,listctrl默认view 风格为report
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( " file://%22)+1/));

           himlSmall 
=  (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir, 
                      
0
                      
& sfi, 
                      
sizeof (SHFILEINFO), 
                      SHGFI_SYSICONINDEX 
|  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();


本文来自CSDN博客,转载请标明出处:http:
// blog.csdn.net/xiaolan458/archive/2008/12/10/3488236.aspx

 

你可能感兴趣的:(list)