怎样让CListCtrl的Item显示多行文字

如题所述

  1

  ClistCtrl有四种样式,ICON,small icon,list,report,其中前三种一般使用的都很少,report是ClistCtrl的重点也是他的精髓,当然这四种样式的样式图例,大家可以参照windows的资源管理器,大图标,小图标,列表和详细信息。现在先说一下前三种的使用方法。
  2
  前三种ICON,small icon,list都是已图标形式存在,那么他的重点也就是怎么加载图标
  首先创建CImageList的对象m_ImageList1
  //创建大图标,Craete创建一个图标列表,当然大小可以随意设置,这里采用的是加载ICON
  if ( m_ImageList1.GetSafeHandle() == NULL )
  {
  m_ImageList1.Create(80,80,ILC_MASK|ILC_COLOR32, 0, 0);
  m_ImageList1.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
  m_ListCtrl1.SetImageList(&m_ImageList1, LVSIL_NORMAL);
  }
  //加载BMP图片
  if (m_StatusImage.GetSafeHandle()==NULL)
  {
  CBitmap Image;
  BITMAP ImageInfo;
  Image.LoadBitmap(IDB_SERVER_LIST_IMAGE);
  Image.GetBitmap(&ImageInfo);
  m_StatusImage.Create(18,ImageInfo.bmHeight,ILC_COLOR16|ILC_MASK,0,0);
  m_StatusImage.Add(&Image,RGB(255,0,255));
  }
  m_ListCtrl2.SetImageList(&m_StatusImage,LVSIL_SMALL);
  m_ListCtrl3.SetImageList(&m_StatusImage,LVSIL_SMALL);
  //插入节点
  for (int i=0;i<40;i++)
  {
  m_ListCtrl1.InsertItem(i, TEXT("Item"));
  m_ListCtrl2.InsertItem(i, TEXT("Item"));
  m_ListCtrl3.InsertItem(i, TEXT("Item"));
  }
  到这里,我们就添加了图标形式的节点,现在在说一下Report的操作方法,当然下面的操作也适用于图标样式,关于ClistCtrl的成员函数讲解,参照MSDN,这里只说明使用方法
  END
  Report风格的CListCtrl的使用
  1
  创建列,也就是为标头控件添加节点
  m_ListCtrl4.InsertColumn( 0, TEXT("Main_1"), LVCFMT_LEFT, 70 );
  m_ListCtrl4.InsertColumn( 1, TEXT("Main_2"), LVCFMT_LEFT, 70 );
  m_ListCtrl4.InsertColumn( 2, TEXT("Main_3"), LVCFMT_LEFT, 70 );
  2
  设置风格
  之前我们修改窗口属性的时候都是使用的SetWindowLong函数或者ModifyStyle,这次CListCtrl为我们提供一个新函数,SetExtendedStyle,当然通过它只能修改扩展属性
  支持的扩展属性很多,但是常用的就几个而已,其他的可以参照msdn,这里讲解两个常用的样式
  LVS_EX_CHECKBOXES:将CListCtrl添加check控件LVS_EX_FULLROWSELECT:未添加该样式,选择一个节点,只能选中节点的第一个元素,而这个属性则可以让选择节点的时候选中整行
  当然这些属性可以多个同时存在
  m_ListCtrl4.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT );
  3
  添加图标,图标的添加方式和ICON样式的添加方式是一样的,这里我们添加bmp图片,在了解另一种添加方式
  //加载BMP图标
  if (m_StatusImage.GetSafeHandle()==NULL)
  {
  CBitmap Image;
  BITMAP ImageInfo;
  Image.LoadBitmap(IDB_SERVER_LIST_IMAGE);
  Image.GetBitmap(&ImageInfo);
  m_StatusImage.Create(18,ImageInfo.bmHeight,ILC_COLOR16|ILC_MASK,0,0);
  m_StatusImage.Add(&Image,RGB(255,0,255));
  }
  m_ListCtrl4.SetImageList(&m_StatusImage,LVSIL_SMALL);
  4
  插入节点并设置节点的文本内容
  void CListCtrlDlg::OnBnClickInsert()
  {
  int nCount = m_ListCtrl4.GetItemCount();
  int nRow = m_ListCtrl4.InsertItem(LVIF_IMAGE|LVIF_TEXT|LVIF_PARAM,0,TEXT("Item_1"),0,0,2,0);
  m_ListCtrl4.SetItemText(nRow, 1, TEXT("Item_2"));
  m_ListCtrl4.SetItemText(nRow, 2, TEXT("Item_3"));
  }
  5
  判断节点是否被Check选中,GetCheck
  void CListCtrlDlg::OnBnClickCheckState()
  {
  CString str,str1=TEXT("被Check的行数分别为:");
  
  for(int i=0; i<m_ListCtrl4.GetItemCount(); i++)
  {
  if( m_ListCtrl4.GetCheck(i))
  {
  str.Format(TEXT("[%d]"),i);
  str1+=str;
  }
  }
  
  AfxMessageBox(str1);
  }
  6
  获取选中行的索引,默认情况下,CListCtrl是支持多选的,支持Ctrl和Shift操作,如果需要单选,可以将控件的Single Selection设为true或者添加LVS_SINGLESEL属性,这里介绍两种方法:
  方法1:我们通过遍历所有行,然后挨行判断当前的状态即可
  CString str,str1=TEXT("选中的行数分别为:");
  for(int i=0; i<m_ListCtrl4.GetItemCount(); i++)
  {
  if( m_ListCtrl4.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
  {
  str.Format(TEXT("[%d]"),i);
  str1+=str;
  }
  }
  AfxMessageBox(str1);
  m_ListCtrl4.SetFocus();
  方法2:通过迭代的方式进行遍历
  POSITION pos = m_ListCtrl4.GetFirstSelectedItemPosition();
  if (pos == NULL)
  {
  str1 = TEXT("没有选中任何节点");
  }
  else
  {
  while (pos)
  {
  int nItem = m_ListCtrl4.GetNextSelectedItem(pos);
  
  str.Format(TEXT("[%d]"),nItem);
  str1+=str;
  }
  }
  
  AfxMessageBox(str1);
  m_ListCtrl4.SetFocus();
  7
  获取列数,这里我们就使用了CHeaderCtrl控件
  int nColumnCount = m_ListCtrl4.GetHeaderCtrl()->GetItemCount();
  8
  获取节点的信息GetItem,这里我们获取最后一行的信息
  void CListCtrlDlg::OnBnClickInfo()
  {
  TCHAR szBuffer[MAX_PATH]=TEXT("");
  CString str=TEXT("节点信息分别为:");
  
  //获取列数
  int nColumnCount = m_ListCtrl4.GetHeaderCtrl()->GetItemCount();
  
  LVITEM lvi;
  lvi.iItem = m_ListCtrl4.GetItemCount()-1;
  lvi.mask = LVIF_TEXT;
  lvi.cchTextMax = CountArray(szBuffer);
  
  for (int i=0;i<nColumnCount; i++)
  {
  lvi.iSubItem = i;
  lvi.pszText = szBuffer;
  m_ListCtrl4.GetItem(&lvi);
  
  str+=TEXT("[");
  str+=szBuffer;
  str+=TEXT("] ");
  }
  
  AfxMessageBox(str);
  }
  9
  滚动到要显示的行上,很多时候,我们的数据比较大,而我们通过查找获取获取到了行数后,我们想快速定位的该行,这里我们就可以用EnsureVisible,这里举例定位到最后一行,并且选中该行
  void CListCtrlDlg::OnBnClickVis()
  {
  int nItem = m_ListCtrl4.GetItemCount()-1;
  m_ListCtrl4.EnsureVisible(nItem, FALSE);
  
  m_ListCtrl4.SetItemState(nItem, LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
  m_ListCtrl4.SetSelectionMark(nItem);
  m_ListCtrl4.SetFocus();
  }
  10
  选中行,注意:这句代码只是让指定行高亮显示,如果使用后再用GetSelectionMark函数来得到选中行,结果往往是错误的。比如,先用鼠标点击选中第5行,调用GetSelectionMark函数得到的是4(第5行),再调用SetItemState函数选中第2行,然后调用GetSelectionMark函数得到的还是4(第5行),所以,需要在设置选中行高亮显示时,一般与SetSelectionMark函数连用
  m_ListCtrl4.SetItemState(nItem, LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
  m_ListCtrl4.SetSelectionMark(nItem);
  m_ListCtrl4.SetFocus();
  11
  取消选中
  void CListCtrlDlg::OnBnClickUnSel()
  {
  for(int i=0; i<m_ListCtrl4.GetItemCount(); i++)
  {
  if( m_ListCtrl4.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
  {
  m_ListCtrl4.SetItemState(i,0,LVIS_SELECTED);
  }
  }
  
  m_ListCtrl4.SetSelectionMark(-1);
  m_ListCtrl4.SetFocus();
  }
  12
  获取标头控件的节点文本
  void CListCtrlDlg::OnBnClickHead()
  {
  LVCOLUMN lvcol;
  TCHAR szBuffer[MAX_PATH]=TEXT("");
  
  int nColumnIndex;;
  
  CString str=TEXT("标题头文本分别为:");
  
  nColumnIndex = 0;
  lvcol.mask = LVCF_TEXT;
  lvcol.pszText = szBuffer;
  lvcol.cchTextMax = CountArray(szBuffer);
  
  while(m_ListCtrl4.GetColumn(nColumnIndex, &lvcol))
  {
  str+=TEXT("[");
  str+= lvcol.pszText;
  str+=TEXT("]");
  
  nColumnIndex++;
  }
  
  AfxMessageBox(str);
  }
  13
  删除所有行
  m_ListCtrl4.DeleteAllItems();
  14
  删除指定行,举例删除最后一行
  m_ListCtrl4.DeleteItem(m_ListCtrl4.GetItemCount()-1);
  15
  删除所有,包括标头控件,这里还是用两种方法去做
  方法1:当删除了节点0之后,下面的节点都会往上移动,重新排列,所以我们只要依次把所有的第一个节点都删除即可
  while( m_ListCtrl4.DeleteColumn(0) );
  方法2:这里和第一种方法原理类似,这次是从后往前删除
  int nColumnCount = m_ListCtrl4.GetHeaderCtrl()->GetItemCount();
  for (int i=nColumnCount-1; i>=0; i--)
  m_ListCtrl4.DeleteColumn (i);
  16
  左键消息,添加ON_NOTIFY的NM_CLICK消息,这里我们举例单击事件的区域位置,即鼠标在哪行哪列点击了,仍然举两种方法
  方法1:
  void CListCtrlDlg::OnLclickList4(NMHDR *pNMHDR, LRESULT *pResult)
  {
  LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
  
  //方法一:
  DWORD dwPos = GetMessagePos();
  CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
  
  m_ListCtrl4.ScreenToClient(&point);
  
  LVHITTESTINFO lvinfo;
  lvinfo.pt = point;
  lvinfo.flags = LVHT_ABOVE;
  int nItem = m_ListCtrl4.SubItemHitTest(&lvinfo);
  
  if(nItem != -1)
  {
  CString str;
  str.Format(TEXT("单击的是第%d行第%d列"), lvinfo.iItem, lvinfo.iSubItem);
  AfxMessageBox(str);
  }
  
  *pResult = 0;
  }
  方法2:
  void CListCtrlDlg::OnLclickList4(NMHDR *pNMHDR, LRESULT *pResult)
  {
  LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
  
  // 方法二:
  NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  if(pNMListView->iItem != -1)
  {
  CString str;
  str.Format(TEXT("单击的是第%d行第%d列"),pNMListView->iItem, pNMListView->iSubItem);
  AfxMessageBox(str);
  }
  
  *pResult = 0;
  }
  17
  右键消息:添加ON_NOTIFY的NM_RCLICK消息,这里举例是右键菜单
  void CListCtrlDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
  {
  NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  if(pNMListView->iItem != -1)
  {
  DWORD dwPos = GetMessagePos();
  CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
  
  CMenu menu;
  if (menu.CreatePopupMenu()==FALSE) return;
  menu.AppendMenu(0,2000,TEXT("菜单节点"));
  menu.AppendMenu(0,2001,TEXT("菜单节点"));
  menu.AppendMenu(0,2002,TEXT("菜单节点"));
  
  menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x,point.y,this);
  }
  *pResult = 0;
  }
温馨提示:内容为网友见解,仅供参考
无其他回答

怎样让CListCtrl的Item显示多行文字
滚动到要显示的行上,很多时候,我们的数据比较大,而我们通过查找获取获取到了行数后,我们想快速定位的该行,这里我们就可以用EnsureVisible,这里举例定位到最后一行,并且选中该行 void CListCtrlDlg::OnBnClickVis() { int nItem = m_ListCtrl4.GetItemCount()-1; m_ListCtrl4.EnsureVisible(nItem, FALSE);m_...

求助,关于clistctrl::insertitem函数的参数
第二个参数是项目的文本内容。这通常是用户要在列表控件中显示的字符串。文本可以是任意字符,包括中英文、数字等,并且支持换行符以展示多行文本。3. 图像索引 第三个参数是图像索引,用于指定列表项旁边的图像。如果你的列表控件包含图像列表,那么可以通过此参数指定与列表项关联的图像的索引。如果不需...

如何快速的向CListCtrl中插入大量的记录(VC)?
先插入一行InsertItem(i,"文本")\/\/插入时顺便写入了第一个项目的文本 再用SetItemText(i,j,"文本")\/\/i表示行数,\/\/j表示一行中的第几个项目

怎样在List control控件中显示多行数据
试试去重写CListCtrl中的DrawItem虚函数来自己绘制,不过也许也不行,自己绘制还不如自定义控件呢!

如何获取CListCtrl当前选中的行
方法一: 单选的情况下 GetNextItem(-1,LVIS_SELECTED);方法二:单选的情况下 如果只允许单选,只需要调用成员函数GetSelectionMark()就可以获取选中的行号,然后你再调用GetItemText()就可以获取选中行的文本。方法三: 可以多选的情况下 CString str;POSITION pos=list.GetFirstSelectedItemPosition(); \/\/...

vc++中clistctr::insertitem的作用是什么?
详细解释如下:一、基本功能 CListCtrl的InsertItem方法允许开发者在列表的特定位置插入新的项目。这个方法通常用于动态地构建或修改列表内容。二、使用方法 使用InsertItem方法时,需要指定插入的位置以及要插入的数据。通常,这个位置是通过索引来指定的,而数据可以是文本或其他格式,这取决于列表控件的具体...

如何获取CListCtrl当前选中的行?
GetCurSel() 这个是CCOMBOBOX里面的,CString str;POSITION pss=m_ListPage.GetFirstSelectedItemPosition();\/\/pos就是行索引号,晕 int i=0;if(pss==NULL)AfxMessageBox("no item were selected!");else { while(pss)\/\/关键,如果你选择多行 { int nIdx=-1;nIdx= m_ListPage....

CListCtrl::GetItemText函数原型
首先,第一个重载函数的原型是:int GetItemText( int nItem, int nSubItem, LPTSTR lpszText, int nLen ) const;在这里,参数nItem代表你想要获取的列表项的索引,从0开始计数。nSubItem参数则表示子项,通常用于多列布局的列表,0通常表示第一列,1表示第二列,以此类推。lpszText是一个指向字符...

CListCtrl中排序怎么实现
第一和第二个参数为用于比较的两项 的ItemData,你可以通过DWORD CListCtrl::GetItemData( int nItem )\/BOOL CListCtrl::SetItemData( int nItem, DWORD dwData )来对每一项的ItemData进行存取。在添加项时选用特定的CListCtrl::InsertItem也可以设置该值。由于你在排序时只能通过该值 来确定项的位置...

求助,关于CListCtrl::InsertItem函数的参数
参考资料:CListCtrl::InsertItem函数接受两个参数:插入位置(整数,从0开始)和项目文本(字符串)。定义域是插入位置范围,值域是实际插入后的显示效果,受函数实现影响。在函数中,自变量(如插入位置)和因变量(如项目文本)的关系是动态的。函数值(如插入后项目的位置和显示内容)由输入参数确定。

相似回答