程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> VC++ 中ListCtrl經歷總結

VC++ 中ListCtrl經歷總結

編輯:關於C++

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老是要的吧,費事啊,所以我臨時是用上述的方法來刪除,也供年夜家參考,願望能找到更好的方法。

以上所述就是本文的全體內容了,願望年夜家可以或許愛好。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved