CListCtrl的使用
更新日期:2011-1-10 示例代碼:demo.zip (請不要使用下載工具,,否則可能出錯) 測試環(huán)境:VC6.0+WinXP 圖片預(yù)覽:
CListCtrl 使用技巧:(這一篇文章寫得很好,,極力推薦) http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx 以下是網(wǎng)上收集的資料,都很不錯:(請不要使用下載工具,,否則可能出錯) http://cid-3ba16e78a53d2d3d.office./self.aspx/VC/ClistCtrl-help.zip
基本樣式和擴張樣式 ━━━━━━━━━━━━━━━━━━━━━━━━ (1)基本樣式 LVS_ICON 大圖標(biāo)顯示方式,; LVS_LIST 列表顯示方式; LVS_SMALLICON 小圖標(biāo)顯示方式,; LVS_REPORT 以詳細(xì)資料即報告方式顯示,; LVS_ALIGNLEFT 表項的大小圖標(biāo)以左對齊方式顯示; LVS_ALIGNTOP 表項的大小圖標(biāo)以頂對齊方式顯示,; LVS_AUTOARRANGE 表項的大小圖標(biāo)以自動排列方式顯示,; LVS_EDITLABELS 設(shè)置表項文本可以編輯,父窗口必須設(shè)有LVN_ENDLABELEDIT風(fēng)格,; LVS_NOCOLUMNHEADER 在詳細(xì)資料方式時不顯示列表頭,; LVS_NOLABELWRAP 以單行方式顯示圖標(biāo)的文本項,; LVS_NOSCROLL 用來屏蔽滾動條,; LVS_NOSORTHEADER 列表頭不能用作按鈕功能; LVS_OWNERDRAWFIXED 在詳細(xì)列表方式時允許自繪窗口,; LVS_SHAREIMAGELISTS 共享圖像列表方式,如果一個程序里有兩個Listctrl同用一個HIMAGELIST,,則其中一個摧毀不會影響另外一個,Specifies that the control does not take ownership of the image lists assigned to it (that is, it does not destroy the image lists when it is destroyed). This style enables the same image lists to be used with multiple list view controls. LVS_SHOWSELALWAYS 一直顯示被選中表項方式,; LVS_SINGLESEL 在某一時刻只能有一項被選中,; LVS_SORTASCENDING 表項排序時是基于表項文本的升序方式; LVS_SORTDESCENDING 表項排序時是基于表項文本的降序方式,;
設(shè)置方法: LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //獲取當(dāng)前窗口style lStyle &= ~LVS_TYPEMASK; //清除顯示方式位 lStyle |=LVS_ICON ; //設(shè)置style SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設(shè)置style
(2)擴展樣式,, CListCtrl控件的擴展樣式,用SetExtendedStyle來改變 LVS_EX_GRIDLINES //繪制表格線(report風(fēng)格時) LVS_EX_FULLROWSELECT //選擇整行(report風(fēng)格時) LVS_EX_SUBITEMIMAGES //子項目圖標(biāo)列表 LVS_EX_CHECKBOXES //帶復(fù)選框 LVS_EX_TRACKSELECT //自動換行 LVS_EX_HEADERDRAGDROP //報表頭可以拖拽 LVS_EX_ONECLICKACTIVATE //單擊激活 LVS_EX_TWOCLICKACTIVATE //雙擊激活 LVS_EX_FLATSB //扁平滾動條 LVS_EX_REGIONAL LVS_EX_INFOTIP LVS_EX_UNDERLINEHOT LVS_EX_UNDERLINECOLD LVS_EX_MULTIWORKAREAS //多工作區(qū)
設(shè)置方法: DWORD dwStyle = m_ListCtrl.GetExtendedStyle(); //獲取當(dāng)前擴展樣式 dwStyle |= LVS_EX_FULLROWSELECT; //選中某行使整行高亮(report風(fēng)格時) dwStyle |= LVS_EX_GRIDLINES; //網(wǎng)格線(report風(fēng)格時) m_ListCtrl.SetExtendedStyle(dwStyle); //設(shè)置擴展風(fēng)格
初始化CListCtrl ━━━━━━━━━━━━━━━━━━━━━━━━ BOOL CDemoDlg::OnInitDialog() { CDialog::OnInitDialog(); /* //自定義圖標(biāo) m_imagelist.Create(16,16,ILC_COLORDDB,2,2); //創(chuàng)建CImageList 16,16是圖標(biāo)的大小 m_imagelist.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME)); //向CImageList中添加圖標(biāo) m_imagelist.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME)); m_ListCtrl.SetImageList(&m_imagelist,LVSIL_SMALL);//把CListCtrl中的CImageList聯(lián) */
//設(shè)置基本樣式 LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //獲取當(dāng)前窗口style lStyle |=LVS_REPORT ; //以詳細(xì)資料即報告方式顯示; lStyle |=LVS_SHOWSELALWAYS ; //一直顯示被選中表項方式,; SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設(shè)置style
//設(shè)置擴展樣式 DWORD dwStyle = m_ListCtrl.GetExtendedStyle(); //獲取當(dāng)前擴展樣式 dwStyle |= LVS_EX_FULLROWSELECT; //選中某行使整行高亮(report風(fēng)格時) dwStyle |= LVS_EX_GRIDLINES; //網(wǎng)格線(report風(fēng)格時) m_ListCtrl.SetExtendedStyle(dwStyle); //設(shè)置擴展風(fēng)格
SHFILEINFO shFinfo; //獲取系統(tǒng)小圖標(biāo) HIMAGELIST hImageListSmall=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO), SHGFI_SYSICONINDEX| SHGFI_SMALLICON);
//獲取系統(tǒng)大圖標(biāo) HIMAGELIST hImageListLarge=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO), SHGFI_SYSICONINDEX| SHGFI_ICON); m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListSmall),LVSIL_SMALL); m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListLarge),LVSIL_NORMAL); // ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL, (LPARAM)hImageList);
//設(shè)置列 m_ListCtrl.InsertColumn(0, "第一列", LVCFMT_LEFT, 150); m_ListCtrl.InsertColumn(1, "第二列", LVCFMT_LEFT, 150); m_ListCtrl.InsertColumn(2, "第三列", LVCFMT_LEFT, 150);
//添加c盤目錄到CListCtrl EnumFiles("c:",m_ListCtrl); //添加數(shù)據(jù) CString strData[3][3] = { { _T("Washington"), _T("George"), _T("1789-1797") }, { _T("Adams"), _T("John"), _T("1797-1801") }, { _T("Jefferson"), _T("Thomas"), _T("1801-1809") } };
for (int i=0; i<3; i++) { m_ListCtrl.InsertItem(i, strData[i][0]); m_ListCtrl.SetItemText(i, 1, strData[i][1]); m_ListCtrl.SetItemText(i, 2, strData[i][2]); m_ListCtrl.SetItemData(i, i); }
return TRUE; // return TRUE unless you set the focus to a control }
以下展示4種視圖間的切換: ━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnRadio1() { LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //獲取當(dāng)前窗口style lStyle &= ~LVS_TYPEMASK; //清除顯示方式位 lStyle |=LVS_ICON ; //設(shè)置style SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設(shè)置style
}
void CDemoDlg::OnRadio2() { LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //獲取當(dāng)前窗口style lStyle &= ~LVS_TYPEMASK; //清除顯示方式位 lStyle |=LVS_LIST ; //修改style SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設(shè)置style }
void CDemoDlg::OnRadio3() { //另外一種簡單的方法 m_ListCtrl.ModifyStyle(LVS_TYPEMASK,LVS_SMALLICON); }
void CDemoDlg::OnRadio4() { LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //獲取當(dāng)前窗口style lStyle &= ~LVS_TYPEMASK; //清除顯示方式位 lStyle |=LVS_REPORT ; //設(shè)置style SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle); //設(shè)置style }
━━━━━━━━━━━━━━━━━━━━━━━━
/**************************************************************************** 插入一行 ****************************************************************************/ void CDemoDlg::OnButton1() { //插入一行數(shù)據(jù),,方法一 int nRow = m_ListCtrl.InsertItem(2,_T("text1"),0); //參數(shù)(行數(shù),標(biāo)題,圖標(biāo)索引) m_ListCtrl.SetItemText(nRow, 1, _T("text2")); //參數(shù)(行數(shù),此行的哪一列,文本) m_ListCtrl.SetItemText(nRow, 2, _T("text3")); //參數(shù)(行數(shù),此行的哪一列,文本)
//插入一行數(shù)據(jù),方法二 LVITEM lvi = {0}; //定義一個數(shù)據(jù)項 lvi.mask = LVIF_TEXT ; //標(biāo)志位 文本 lvi.iItem = 3 ; //此項是3行,可修改為想要插入的行 lvi.iSubItem = 0; //此項是第幾列的數(shù)據(jù) lvi.iImage =1; //第幾個圖標(biāo) lvi.pszText =_T("jacky_qiu"); //文本 m_ListCtrl.InsertItem(&lvi); // ::SendMessage(m_ListCtrl.m_hWnd, LVM_INSERTITEM, 0,(LPARAM)&lvi);
//當(dāng)插入item后調(diào)用SetColumnWidth可以自動變寬度大小 m_ListCtrl.SetColumnWidth ( 0, LVSCW_AUTOSIZE_USEHEADER ); m_ListCtrl.SetColumnWidth ( 1, LVSCW_AUTOSIZE_USEHEADER ); m_ListCtrl.SetColumnWidth ( 2, LVSCW_AUTOSIZE_USEHEADER ); }
━━━━━━━━━━━━━━━━━━━━━━━━ /**************************************************************************** 修改一行 ****************************************************************************/ void CDemoDlg::OnButton2() { //修改某行某列的數(shù)據(jù) LVITEM lvi = {0}; //定義一個數(shù)據(jù)項 lvi.mask = LVIF_TEXT ; //標(biāo)志位 (指明需要修改什么) lvi.iItem = 2 ; //需要修改的項的索引 lvi.iSubItem = 0; //此項是第幾列的數(shù)據(jù) lvi.iImage =1; //第幾個圖標(biāo) lvi.pszText =_T("修改"); //修改的文本 //mfc m_ListCtrl.SetItem(&lvi); //修改這一項,此項一定要存在 //win32 api ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, NULL, (LPARAM)&lvi); }
━━━━━━━━━━━━━━━━━━━━━━━━ /**************************************************************************** 單選情況下刪除一行 ****************************************************************************/ void CDemoDlg::OnButton3() { m_ListCtrl.DeleteItem(2); }
━━━━━━━━━━━━━━━━━━━━━━━━ /**************************************************************************** 刪除選擇的多行 ****************************************************************************/ void CDemoDlg::OnButton6() { //刪除選中的多行 POSITION sSelPos = NULL; int nSelItem; while(sSelPos = m_ListCtrl.GetFirstSelectedItemPosition()) { nSelItem = m_ListCtrl.GetNextSelectedItem(sSelPos); if(nSelItem >= 0 && nSelItem<m_ListCtrl.GetItemCount()) m_ListCtrl.DeleteItem(nSelItem); } }
━━━━━━━━━━━━━━━━━━━━━━━━ /**************************************************************************** 獲取選中行 ****************************************************************************/ void CDemoDlg::OnButton5() { /* { int SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0)); if (SelectItem==-1) { ::MessageBox(m_hWnd,TEXT("請至少選擇一個文件"),NULL,MB_OK); return; } do //獲取選中的多個項,; { } while(-1!=(SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,SelectItem,MAKELPARAM(LVNI_SELECTED,0)))); } */
//獲得選中的行(選中多行) POSITION pos=m_ListCtrl.GetFirstSelectedItemPosition(); if(pos!= NULL) { while (pos) { int nItem=m_ListCtrl.GetNextSelectedItem(pos); trace("選中了",nItem); } }
//獲取選中的多個項,; int SelectItem=-1; while(-1!=(SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,SelectItem,MAKELPARAM(LVNI_SELECTED,0)))) { trace("選中了:",SelectItem); }
//判斷是否一項也沒有選中 if( -1!=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0))) { trace("選中了至少一項"); } else { trace("沒有選中一項"); }
//如果ListCtrl是單選的,就用這種方式判斷選中的項 SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0)); if (SelectItem!=-1) { //get the item TCHAR szBuf[1024];
LVITEM lvi; lvi.iItem = SelectItem; lvi.pszText = szBuf; lvi.cchTextMax = sizeof(szBuf)/sizeof(TCHAR); lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_DI_SETITEM;
//第一列 lvi.iSubItem = 0; ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi); trace(SelectItem,lvi.iSubItem,szBuf);
//第二列 lvi.iSubItem = 1; ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi); trace(SelectItem,lvi.iSubItem,szBuf);
{ TCHAR szBuf[1024]; LVITEM lvi; lvi.pszText = szBuf; lvi.cchTextMax =sizeof(szBuf)/sizeof(TCHAR); lvi.iSubItem =0; lvi.mask = LVIF_TEXT;
int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0);
for(int i=0; i<count; i++) { ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)&lvi); trace(SelectItem,lvi.iSubItem,lvi.pszText); } }
{ int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0); for(int i=0; i<count; i++) { TCHAR szBuf[MAX_PATH]; m_ListCtrl.GetItemText(i,0,szBuf,sizeof(szBuf)/sizeof(TCHAR)); trace(szBuf); } } } }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnFind() { //尋找一個item LVFINDINFO FindInfo; FindInfo.flags = LVFI_STRING ; FindInfo.psz ="windows"; // int nItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_FINDITEM,-1,(LPARAM)&FindInfo); int nItem=m_ListCtrl.FindItem(&FindInfo); if (nItem!=-1) { tracef("找到 %s,,在 %d 行",FindInfo.psz,nItem); } else { tracef("找不到 %s ",FindInfo.psz); } }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnButton7() { //獲得一項的圖標(biāo) LVITEM lvi={0}; lvi.iItem = 6; //獲取第6項 lvi.mask =LVIF_IMAGE; m_ListCtrl.GetItem(&lvi); tracef("image index : %d",lvi.iImage); }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnButton8() { //需要設(shè)置dwStyle |= LVS_SHOWSELALWAYS; //當(dāng)List control獲得焦點時 才會高亮度成藍(lán)色的,, //如果List control沒有焦點,選中的項只是灰色的
//選中一個item,,方法一 m_ListCtrl.SetItemState(1,LVIS_SELECTED,LVIS_SELECTED);
//選中一個item,,方法二 LVITEM lviItem; lviItem.stateMask=LVIS_SELECTED ; lviItem.state=LVIS_SELECTED; ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 2,(LPARAM) &lviItem);
//選中一個item,方法三 LVITEM lvi={0}; lvi.iItem = 3; lvi.mask = LVIF_STATE; lvi.stateMask=LVIS_SELECTED ; lvi.state=LVIS_SELECTED; ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi); { //取消選中第5項目,,方法一 m_ListCtrl.SetItemState(5,0,LVIS_SELECTED); //取消選中第4項目,,方法二 LVITEM lviItem; lviItem.stateMask=LVIS_SELECTED ; lviItem.state=0; ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 4,(LPARAM) &lviItem); //取消選中第6項目,方法三 LVITEM lvi={0}; lvi.iItem =6; lvi.mask = LVIF_STATE; lvi.stateMask=LVIS_SELECTED ; lvi.state=0; ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi); } }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnButton13() { //獲取第2行的選中狀態(tài),,方法一 LVITEM lvi={0}; lvi.iItem = 2; lvi.mask = LVIF_STATE; lvi.stateMask=LVIS_SELECTED ; //lvi.mask 必須指定LVIF_STATE // ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM) &lvi); m_ListCtrl.GetItem(&lvi); if (lvi.state|LVIS_SELECTED==1) { trace("第2行 select"); } else { trace("第2行 no select"); } //獲取第3行的選中狀態(tài),方法二 int state=(int)::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMSTATE,3,(LPARAM) LVIS_SELECTED); if (state|LVIS_SELECTED==1) { trace("第3行 select"); } else { trace("第3行 no select"); } }
━━━━━━━━━━━━━━━━━━━━━━━━
//鼠標(biāo)點擊 void CDemoDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if(pNMListView->iItem != -1) //假如沒有選中一項 { tracef("單擊的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem); }
/* NM_LISTVIEW* pList = (NM_LISTVIEW*)pNMHDR; if(-1 != pList->iItem) { static CEdit* pEdit=NULL; CRect rect; m_ListCtrl.GetSubItemRect(pList->iItem, pList->iSubItem, LVIR_BOUNDS, rect); if(NULL == pEdit) { pEdit = new CEdit(); pEdit->Create(ES_AUTOHSCROLL|WS_CHILD, rect, &m_ListCtrl, 34234); pEdit->SetFont(m_ListCtrl.GetFont()); pEdit->SetWindowText(m_ListCtrl.GetItemText(pList->iItem, pList->iSubItem)); } pEdit->MoveWindow(rect); pEdit->ShowWindow(SW_SHOW); } */ *pResult = 0; }
void CDemoDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if(pNMListView->iItem != -1) //假如選中一項 { tracef("雙擊的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem); }
*pResult = 0; }
━━━━━━━━━━━━━━━━━━━━━━━━
/**************************************************************************** 獲取item的矩形 ****************************************************************************/ void CDemoDlg::OnButton10() { RECT ItemRect; // ItemRect.left=LVIR_LABEL ; //Returns the bounding rectangle of the item text. // ItemRect.left=LVIR_BOUNDS ; //Returns the bounding rectangle of the entire item, including the icon and label. // ItemRect.left=LVIR_ICON ; //Returns the bounding rectangle of the icon or small icon. ItemRect.left=LVIR_SELECTBOUNDS;//Returns the union of the LVIR_ICON and LVIR_LABEL rectangles, but excludes columns in details view.
::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMRECT , 1,(LPARAM)&ItemRect);
HeightLightRect(m_ListCtrl.m_hWnd,ItemRect,true); trace(ItemRect); }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnButton11() { m_ListCtrl.SetBkColor(RGB(200, 200, 200)); //設(shè)置背景顏色 m_ListCtrl.SetTextBkColor(RGB(200, 200, 200)); //設(shè)置文本背景顏色 m_ListCtrl.SetTextColor(RGB(10, 10, 80)); //設(shè)置文本顏色 m_ListCtrl.Update(0); }
━━━━━━━━━━━━━━━━━━━━━━━━ void CDemoDlg::OnButton15() { //使某項可見,,(出現(xiàn)在窗口里) // m_ListCtrl.EnsureVisible(1,FALSE); ::SendMessage(m_ListCtrl.m_hWnd, LVM_ENSUREVISIBLE, 10,(LPARAM) false); m_ListCtrl.SetItemState(10,LVIS_SELECTED,LVIS_SELECTED); //選中 }
━━━━━━━━━━━━━━━━━━━━━━━━ /**************************************************************************** 右鍵點擊時出現(xiàn)編輯框, 屬性必須設(shè)置為 LVS_EDITLABELS ****************************************************************************/ void CDemoDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult) { UINT nFlag; CPoint point; GetCursorPos(&point); m_ListCtrl.ScreenToClient(&point); int nItem = m_ListCtrl.HitTest(point, &nFlag); if (nItem >= 0) m_ListCtrl.EditLabel(nItem); *pResult = 0; }
//編輯后修改文本 void CDemoDlg::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; LVITEMA item = pDispInfo->item; CString str = item.pszText; str.TrimLeft(); str.TrimRight(); if (str.GetLength() > 0) m_ListCtrl.SetItemText(item.iItem,item.iSubItem,item.pszText); *pResult = 0; }
|