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;iiItem;
}
}
現在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=0;k--) //注意要從後往前刪,否則出錯
m_ListCtrl.DeleteColumn(k);
m_ListCtrl.DeleteAllItems();
用下面的語句建立列:
m_ListCtrl.InsertColumn(0,_T("檔案名稱"),LVCFMT_IMAGE|LVCFMT_LEFT);
m_ListCtrl.InsertColumn(1,_T("儀器類別"));
m_ListCtrl.InsertColumn(2,_T("項目類別"));
其中LVCFMT_IMAGE表示可以在第一列加入表徵圖。如果不要表徵圖可以刪去。
然後設定列寬:
for(j=0;j
上一篇:視窗樣式參考列表
下一篇:安裝過程中報錯:“需要HD Audio匯流排驅動程式”