VC++ 中ListCtrl經歷總結。本站提示廣大學習愛好者:(VC++ 中ListCtrl經歷總結)文章只能為提供參考,不一定能成為您想要的結果。以下是VC++ 中ListCtrl經歷總結正文
先注明一下,這裡,我們用m_listctrl來表現一個CListCtrl的類對象,然後這裡我們的ListCtrl都是report情勢,至於其他的如甚麼年夜圖標,小圖標的臨時不講,究竟report是年夜眾話的應用。其次,我們這裡用條目一,條目二來描寫第一點,第二點,這個是參照《Effective C++》的叫法,俺認為這麼叫比擬COOL :)
條目一:設置ListCtrl的作風
在CSDN上經常看到有人問怎樣設置作風的,他們ListCtrl的模樣是一個列表,有橫條和豎條分界限,然後選中一行,要整一行都選中,而不是只要某一列被選中,等等,這裡給一個比擬周全的設置辦法。
//取得原有作風 DWORD dwStyle = ::GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE); dwStyle &= ~(LVS_TYPEMASK); dwStyle &= ~(LVS_EDITLABELS); //設置新作風 SetWindowLong(m_listctrl.m_hWnd, GWL_STYLE,dwStyle, |LVS_REPORT | LVS_NOLABELWRAP | LVS_SHOWSELALWAYS); //設置擴大作風 DWORD styles = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES; ListView_SetExtendedListViewStyleEx(m_listctrl.m_hWnd, styles, styles );
個中LVS_EX_FULLROWSELECT 就是後面說得整行選中
LVS_EX_GRIDLINES 網格線(只實用與report作風的listctrl)
LVS_EX_CHECKBOXES 後面加個checkbox
pListCtrl->SetExtendedStyle( m_listctrl.GetExtendedStyle() | LVS_EX_SUBITEMIMAGES);
這也是一個很主要的屬性,如許的話,可以在列表中加ICON,記得windows的義務治理器嗎,你想做得那樣,這個屬性也要加哦,這個我今後會講的~
條目二:參加列頭
這是一個比擬本質的器械,給列表框排列,然後加上列頭,代碼措辭,來了
TCHAR rgtsz[2][10] = {_T("列頭1"), _T("列頭2")}; LV_COLUMN lvcolumn; CRect rect; m_listctrl.GetWindowRect(&rect); for(int i=0;i<2;i++) { lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER; lvcolumn.fmt = LVCFMT_LEFT; lvcolumn.pszText = rgtsz[i]; lvcolumn.iSubItem = i; lvcolumn.iOrder = i; if(i==0) { lvcolumn.cx = rect.Width()*3/5 ; } else lvcolumn.cx = rect.Width()*2/5; m_listctrl.InsertColumn(i, &lvcolumn); }
這是拔出兩列的做法,你要拔出20列??隨意你,依樣畫葫蘆~~
lvcolumn.mask 中誰人mask可以有各類屬性,詳細去看msdn吧,
條目三:把記載,拔出列表框中
int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); }
nIndex 是以後的行數,然後把新的一行,插在最上面,
條目四:給列表中拔出圖標
在report格局中,也能拔出圖標
持續代碼措辭
m_image是個CImageList對象
m_image.Create(16,16, TRUE|ILC_COLOR24, 3, 1); m_listctrl.SetImageList(&m_image,LVSIL_SMALL);
然後挪用CImageList的成員函數int CImageList::Add( HICON hIcon );
把ICON拔出到imagelist,
然後在拔出記載的時刻
lvitemAdd.mask = LVIF_TEXT; lvitemAdd.mask = LVIF_TEXT|LVIF_IMAGE
然後添加一個lvitemAdd.iImage = n;
這個n是imagelist中的序號,表現是詳細的哪個圖標,list麼,呵呵
條目五:拔出記載時應用額定的信息,lParam 的應用
有時刻,你想關於某一行,參加一些額定的信息,那末便可以應用這個lParam
msdn是這麼描寫的Specifies the 32-bit value of the item
我前次是為了在某一行參加一個信息,窗口句柄,然後是這麼加的,
int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; lvitemAdd.iImage = n; lvitemAdd.lParam = (LPARAM)hwnd;(某個窗口的窗口句柄) if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); }
ok,這是一個比擬全的例子的,又插ICON,又應用PARAM的
條目六 : 點擊列表框,獲得選中行信息
呼應NM_CLICK新聞,假如你有MSDN,可以看到,有專門關於listview的NM_CLICK的引見
void CMyDlg::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int nItem = -1; LPNMITEMACTIVATE lpNMItemActivate = (LPNMITEMACTIVATE)pNMHDR; if(lpNMItemActivate != NULL) { nItem = lpNMItemActivate->iItem; } }
如今nItem就是點擊選中那行的index了,有了index,獲得那行的信息還難嗎
懶漢說:難,由於你還沒講,暈,那就持續說
條目七: 依據行的index,獲得該行的信息
直接上代碼吧
LV_ITEM lvitem = {0}; lvitem.iItem = nIndex; lvitem.iSubItem = 0; lvitem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; m_listctrl.GetItem(&lvitem)
如許,就把nindex,第一列的信息掏出來了,包含適才我們參加的ICON,和誰人額定信息(窗口句柄),好比我要獲得窗口句柄,便可以hwnd = (HWND)lvitem.lParam;
mask 用來指明你想獲得那些信息
詳細可以查msdn中LVITEM Structure的界說和CListCtrl::GetItem
條目八:用法式選中某一行,使之選中
選中之
m_listctrl.SetItemState(nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
不選中,撤消選中之
m_listctrl.SetItemState(nIndex,0,LVIS_SELECTED|LVIS_FOCUSED);
條目九:獲得以後一切選中的行(多選)
這個,俺就比擬懶了,抄msdn的代碼吧,橫豎很簡略
// CListCtrl* pListCtrl = (CListCtrl*) GetDlgItem (IDC_YOURLISTCONTROL); ASSERT(pListCtrl != NULL); POSITION pos = pList->GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = pList->GetNextSelectedItem(pos); TRACE1("Item %d was selected!\n", nItem); // you could do your own processing on nItem here } }
條目十:刪除條目九當選中的行
這個絕對後面九個條目是比擬費事的,由於假如你要刪除多行的話,常常要失足。好比,我如今要刪除第0行和第1行(列表的行序列是從0開端的)
那末好啊。我來刪了
m_listctrl.DeleteItem(0) m_listctrl.DeleteItem(1)
祝賀你,錯了,我好高興啊 :)
由於你刪除第0行今後,上面的行會往上移,那末本來的第1行就釀成了第0行,那末你再 m_listctrl.DeleteItem(1),那末刪除的是本來的第2行,真費事,
所以,只要從下往上刪,才是平安的,先刪的,不會影響前面的操作,
m_listctrl.DeleteItem(1) m_listctrl.DeleteItem(0)
但有時刻,我們也不曉得要刪除哪些行,只曉得要刪除選中的那些行,像條目九中的那些
假如我們照樣用
POSITION pos = m_listctrl.GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = m_listctrl.GetNextSelectedItem(pos); m_listctrl.DeleteItem(nItem ); } }
你就等著收屍吧
這時候候我們就要B4微軟了,為蝦米木有GetLastselectedItemPosition 和GetPrevSelectedItem,多寫一對成員函數會逝世啊 :(
沒方法,方法本身想,這裡有個笨方法
POSITION sSelPos = NULL; while(sSelPos = m_listctrl.GetFirstSelectedItemPosition()) { int nSelItem = -1; nSelItem = m_listctrl.GetNextSelectedItem(sSelPos); if(nSelItem >= 0 && nSelItem<m_listctrl.GetItemCount()) { //好了,這個nSelItem 就是我們要的DD } } GetNextSelectedItem這個函數,
看msdn的用法,實際上是前往第一個的index,然後走到下一個選中的行去,所以這麼做也是平安的,在現實中,俺也是這麼做的,測試也經由過程,沒成績的
固然,還有個方法,先經由過程GetFirstSelectedItemPosition和GetNextSelectedItem來獲得一切的選中行的index,然後把這些index放到一個數組裡,然後再從下往上刪
唉真費事啊,還要不定命組,不說用new在堆上開吧,那末一個vector老是要的吧,費事啊,所以我臨時是用上述的方法來刪除,也供年夜家參考,願望能找到更好的方法。
以上所述就是本文的全體內容了,願望年夜家可以或許愛好。