VC中ListCtrl經驗總結

來源:互聯網
上載者:User
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匯流排驅動程式”
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.