CListCtrl的用法

1. CListCtrl 样式及设置

2. 扩展样式设置

3. 数据插入

4. 一直选中Item

5. 选中和取消选中Item

6. 得到CListCtrl中所有行的checkbox的状态

7. 得到CListCtrl中所有选中行的序号

8. 得到item的信息

9. 得到CListCtrl的所有列的header字符串内容

10. 使CListCtrl中一项可见,即滚动滚动条

11. 得到CListCtrl列数

12. 删除所有列

13. 得到单击的CListCtrl的行列号

14. 判断是否点击在CListCtrl的checkbox上

15. 右键点击CListCtrl的item弹出菜单

16. CListCtrl进行大数据量更新时,避免闪烁



--------------------------------------------------------------------------------

1. CListCtrl 样式及设置
LVS_ICON: 每个item显示大图标
LVS_SMALLICON: 每个item显示小图标
LVS_LIST: 显示一列带有小图标的item
LVS_REPORT: 显示item详细资料

如windows资源管理器,“查看”标签下的“大图标,小图标,列表,详细资料”

LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |= LVS_REPORT; //设置style
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle); //设置style


--------------------------------------------------------------------------------

2. 扩展样式设置


DWORD dwStyle = m_ListCtrl.GetExtendedStyle(); //获取当前扩展样式
dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使整行高亮(report风格时)
dwStyle |= LVS_EX_GRIDLINES; //网格线(report风格时)
dwStyle |= LVS_EX_CHECKBOXES; //item前生成checkbox控件
m_ListCtrl.SetExtendedStyle(dwStyle); //设置扩展风格


--------------------------------------------------------------------------------

3. 数据插入

m_ListCtrl.InsertColumn(0,"名称",LVCFMT_LEFT,50); //插入列
m_ListCtrl.InsertColumn(1,"备注",LVCFMT_LEFT,50);

//直接插入:

int nRow=m_ListCtrl.InsertItem(0, "VC++");        //插入行
m_ListCtrl.SetItemText(nRow,1,"Visual C++ 6.0");  //设置数据

//LVITEM 结构插入:

LVITEM item={0};
item.iItem=0;  //行号
item.mask=LVIF_TEXT; /*LVIF_IMAGE支持图标*/;
item.cchTextMax=15;//插入字符串长度
item.pszText="Visual C++ 6.0";

int nRow=m_ListCtrl.InsertItem(&item);

m_ListCtrl.SetItemText(nRow,1,"Visual C++ 6.0");


--------------------------------------------------------------------------------

4. 一直选中Item

选中style中的 Show selection always,

或者添加扩展样式 LVS_SHOWSELALWAYS


--------------------------------------------------------------------------------

5. 选中和取消选中Item
int nIndex = 0;
//选中
  m_ListCtrl.SetItemState(nIndex,LVIS_SELECTED|

  LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
//取消选中
  m_ListCtrl.SetItemState(nIndex,0,LVIS_SELECTED|LVIS_FOCUSED);


--------------------------------------------------------------------------------

6. 得到CListCtrl中所有行的checkbox的状态
CString str;
for(int i=0; i<m_ListCtrl.GetItemCount(); i++)

{
   if(m_ListCtrl.GetItemState(i, LVIS_SELECTED)==

    LVIS_SELECTED || m_ListCtrl.GetCheck(i))
   {
     str.Format(_T("第%d行的checkbox为选中状态"), i);
     AfxMessageBox(str);
    }

  }


--------------------------------------------------------------------------------

7. 得到CListCtrl中所有选中行的序号

//方法一:
  CString str;
  for(int i=0; i<m_ListCtrl.GetItemCount(); i++)
  {
    if(m_ListCtrl.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
    {
      str.Format(_T("选中了第%d行"), i);
      AfxMessageBox(str);
     }
   }

//方法二:
  POSITION pos=m_ListCtrl.GetFirstSelectedItemPosition();
  if(pos==NULL)
   TRACE0("No items were selected!\n");
  else
  {
   while(pos)
    {
      int nItem=m_ListCtrl.GetNextSelectedItem(pos);
      TRACE1("Item %d was selected!\n", nItem);
      //添加其他操作

     }
   }


--------------------------------------------------------------------------------

8. 得到item的信息
TCHAR szBuf[1024];
LVITEM lvi;
lvi.iItem = nItemIndex;
lvi.iSubItem = 0;
lvi.mask = LVIF_TEXT;
lvi.pszText = szBuf;
lvi.cchTextMax = 1024;
m_ListCtrl.GetItem(&lvi);

关于得到设置item的状态,还可以参考msdn文章
Q173242: Use Masks to Set/Get Item States in CListCtrl
http://support.microsoft.com/kb/173242/en-us


--------------------------------------------------------------------------------

9. 得到CListCtrl的所有列的header字符串内容
LVCOLUMN lvcol;
char  str[256];
int   nColNum;
CString strColumnName[3];//假如有3列

nColNum = 0;
lvcol.mask = LVCF_TEXT;
lvcol.pszText = str;
lvcol.cchTextMax = 256;
while(m_list.GetColumn(nColNum, &lvcol))
{
   strColumnName[nColNum] = lvcol.pszText;
   nColNum++;
  }


--------------------------------------------------------------------------------

10. 使CListCtrl中一项可见,即滚动滚动条
m_ListCtrl.EnsureVisible(i, FALSE);


--------------------------------------------------------------------------------

11. 得到CListCtrl列数
int nHeadNum=m_ListCtrl.GetHeaderCtrl()->GetItemCount();


--------------------------------------------------------------------------------

12. 删除所有列
方法一:
  while(m_ListCtrl.DeleteColumn(0))
  //因为你删除了第一列后,后面的列会依次向上移动。

方法二:
  int nColumns = 3; //列数
  for(int i=nColumns-1; i>=0; i--)

   m_ListCtrl.DeleteColumn(i);


--------------------------------------------------------------------------------

13. 得到单击的CListCtrl的行列号
添加listctrl控件的NM_CLICK消息相应函数
void CMyDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
  //方法一:

  DWORD dwPos=GetMessagePos();
  CPoint point( LOWORD(dwPos), HIWORD(dwPos));

  m_ListCtrl.ScreenToClient(&point);

  LVHITTESTINFO lvinfo;
  lvinfo.pt=point;
  lvinfo.flags=LVHT_ABOVE;

  int nItem=m_ListCtrl.SubItemHitTest(&lvinfo);
  if(nItem!=-1)
  {
    CString strtemp;
    strtemp.Format("单击的是第%d行第%d列",

    lvinfo.iItem, lvinfo.iSubItem);
    AfxMessageBox(strtemp);
   }

  // 方法二:
  NM_LISTVIEW* pNMListView=(NM_LISTVIEW*)pNMHDR;
  if(pNMListView->iItem!=-1)
  {

    CString strtemp;
    strtemp.Format("单击的是第%d行第%d列",
    pNMListView->iItem, pNMListView->iSubItem);
    AfxMessageBox(strtemp);
   }

   *pResult = 0;

}


--------------------------------------------------------------------------------

14. 判断是否点击在CListCtrl的checkbox上
添加listctrl控件的NM_CLICK消息相应函数
void CMyDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{

   DWORD dwPos=GetMessagePos();
   CPoint point(LOWORD(dwPos), HIWORD(dwPos));

   m_ListCtrl.ScreenToClient(&point);

   LVHITTESTINFO lvinfo;
   lvinfo.pt=point;
   lvinfo.flags=LVHT_ABOVE;
    
   UINT nFlag;
   int nItem=m_ListCtrl.HitTest(point, &nFlag);
   //判断是否点在checkbox上
   if(nFlag==LVHT_ONITEMSTATEICON)
   {
     AfxMessageBox("点在listctrl的checkbox上");
   }
   *pResult = 0;
}


--------------------------------------------------------------------------------

15. 右键点击CListCtrl的item弹出菜单
添加CListCtrl控件的NM_RCLICK消息相应函数
void CMyDlg::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;
     VERIFY( menu.LoadMenu( IDR_MENU1 ) );
     CMenu* popup = menu.GetSubMenu(0);
     ASSERT( popup != NULL );
     popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,

     point.x, point.y, this );

    }
    *pResult = 0;

}


--------------------------------------------------------------------------------

16. CListCtrl进行大数据量更新时,避免闪烁
m_ListCtrl.SetRedraw(FALSE);
//更新内容
m_ListCtrl.SetRedraw(TRUE);
m_ListCtrl.Invalidate();
m_ListCtrl.UpdateWindow();







CListCtrl 在小型数据库中应用的还是比较多的.因此掌握它是一个很重要的技能.最近在做老师布置的一个项目,用到它,开始的时候不知所措.后来上网找了一些资料,再加上自己的探索,终于对它有一个比较全面的认识.下面我简单讲讲它的一些用法,以此和大家共享一下. 



1.     基本风格设置



      (1)函数:  ModifyStyle( )


      (2)重要参数:    LVS_ICON  // 大图标


                                 LVS_SMALLICON // 小图标


                                 LVS_LIST  // 列表


                                 LVS_REPORT  // 报表


   (3)说明:


用的比较多的是最后的报表视图.因为它可以有多列,正好代表数据库中的多个属性.所以下面的用法都是针对这种风格的.当然这些风格也可以在控件的属性中设置。注意:我们知道在窗口各种各样的风格之间,有时是可以用” |”,表示属性叠加.如:


                          WS_CHILD | WS_VISIBLE;


但是上面的四种风格是不可能放在一起的.所以不要用到 “ |”操作符.


也正是因此,防止用户出错, 微软干脆把LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT这些都不设置成位标志,因此不能叠加.同时还设置了一个多余的掩码:LVS_TYPEMASK.它是用来屏蔽的.



(5) 举例:


   如果我们要判断一个CListCtrl的风格:


              DWORD dwStyle = m_listctrl.GetStyle( );


      // 判断是否大图标样式


              If ( dwStyle & LVS_ICON )


                            …….


             这种写法是错误的.正确的写法涉及到掩码:


                     DWORD dwStyle = m_listctrl.GetStyle( ) & LVS_TYPEMASK;


                     If ( dwStyle = = LVS_ICON)


                     …….


             同理,我们在改变风格时,应该这样写:


                     ModifyStyle( LVS_TYPEMASK, LVS_ICON);




2.     扩展风格设置



    (1) 函数 : SetExtendedStyle( )   GetExtendedStyle ( )


(2) 重要参数:


                       LVS_EX_FULLROWSELECT //选中某行使整行高亮(只适用与报表风格)


                       LVS_EX_GRIDLINES //网格线(只适用与报表风格)


                       LVS_EX_CHECKBOXES //设置checkbox状态


(3)举例


                     DWORD dwStyle = GetExtendedStyle();


                     dwStyle |= LVS_EX_FULLROWSELECT;


                     dwStyle |= LVS_EX_GRIDLINES;


                     SetExtendedStyle(dwStyle);




3.其他风格设置:


函数: SetTextColor ( )  // 设置文字颜色


SetBkColor ( ) // 设置边框颜色


SetTextBkColor ( ) // 设置文字背景颜色




//下面直接举例说明



4.图标设置


可以给大图标风格和小图标风格设置图标:


HICON icon=AfxGetApp()->LoadIcon(IDI_ICON1);


m_icon.Add(icon);


m_listctrl.SetImageList(&m_icon,LVSIL_SMALL);//小图标


      m_listctrl.SetImageList(&m_icon,LVSIL_NORMAL)// 大图标




5插入一列


m_listctrl.InsertColumn(0,”哈哈”,LVCFMT_LEFT,80);


其中: 0是索引项,”哈哈”是列标题,LVCFMT_LEFT是显示方式(靠左),80表示列的宽




6插入一行


m_listctrl.InsertItem(0, “123”,0);// 插入为第一行第一列的内容,最后一个0是图标的索引


m_listctrl.SetItemText( 0,1, “123”) ; // 设置第一行第2列的内容


       m_ listctrl.SetItemText(0,2, “123”) ; // 设置第一行第3列的内容




7得到所有的行数


m_listctrl.GetItemCount( ) ;




8.得到所有的列数


m_listctrl.GetHeaderCtrl().GetItemCount( ) ;




9.得到被单击的项的行列号


void Cmylist::OnClick(NMHDR* pNMHDR, LRESULT* pResult) //单击消息


{


      


       NM_LISTVIEW *info=(NM_LISTVIEW*)pNMHDR;


       selectedIndex=info->iItem; // 行号


       selectedsub=info->iSubItem; // 列号


}    


(Cmylist为CListCtrl的派生类,以selectedIndex和selectedsub为接口,方便使用)       



            


10.得到被单击的列头索引号


void Cmylist::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)


{


       NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;


        selectedField=pNMListView->iSubItem;//列头号


}


同上,也是以selectedField为接口,方便用户调用




11.选中或者取消一行


plistctrl->SetItemState(index,LVIS_SELECTED,LVIS_SELECTED);//选中一行


plistctrl->SetItemState(index,0,LVIS_SELECTED);//取消一行


DWORD style=plistctrl->GetItemState(index,LVIS_SELECTED);//获得选中信息




12.获得被选中的多行


              POSITION p=m_listctrl.GetFirstSelectedItemPosition();// 得到第一次选中的位置


              while(p)


              {


                     int index=m_listctrl.GetNextSelectedItem(p);


                     …


              }




13.删除一行或者一列


        m_listctrl.DeleteItem( index );


       m_listctrl.DeleteColumn(index);




14.删除多行或者多列


       注意要从后面开始删起,比如,如果我想删除第一行和第二行,应该:


              m_listctrl.DeleteItem(1);


              m_listctrl.DeleteItem(0);


       而不能:


              m_listctrl.DeleteItem(0);


m_listctrl.DeleteItem(1);


       因为每次删除一行或者一列,后面的索引号都要变化,所以从后面开始删除就没关系.


如果用for循环,应该递减:


       For(int k=m_listctrl.GetItemCount( );k>=-1;k++)


              m_listctrl.DeleteItem(k);


这就是删除所有行,当然也可以用CListCtrl::DeleteAllItems




15 根据索引号得到某一列的信息


                     HDITEM   hdi;  


                     TCHAR     lpBuffer[256];    


                     hdi.mask   =   HDI_TEXT;  


                     hdi.pszText   =   lpBuffer;  


                     hdi.cchTextMax   =   256;  


                     plistctrl->GetHeaderCtrl()->GetItem(index,   &hdi);


                     CString str=hdi.pszText;

 

排序:

struct MyData...{
     CListCtrl
*listctrl;                 //CListCtrl控件指针
     int isub;        //l列号
     int seq;        //1为升序,0为降序
}
;

//次函数为非常重要函数。
int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
...{
     MyData
*p=(MyData *)lParamSort;
     CListCtrl
* list =p->listctrl;
    
int isub=p->isub;
     LVFINDINFO findInfo;
     findInfo.flags
= LVFI_PARAM;
     findInfo.lParam
= lParam1;
    
int iItem1 = list->FindItem(&findInfo, -1);
     findInfo.lParam
= lParam2;
    
int iItem2 = list->FindItem(&findInfo, -1);
     CString strItem1
=list->GetItemText(iItem1,isub);
     CString strItem2
=list->GetItemText(iItem2,isub);
    
if(p->seq)
         
return strcmp(strItem2, strItem1);
    
else
         
return -strcmp(strItem2, strItem1);
}

然后,在CSortAView类的 OnInitialUpdate 中添加:

    SetProp(m_list.GetSafeHwnd(), " SORT_COLUMN " ,(HANDLE) 0 );
    SetProp(m_list.GetSafeHwnd(),
" SORT_DIRECTION " ,(HANDLE) 1 );
   
// 为listctrl添加列头
    m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
      m_list.InsertColumn(
0 , " 姓名 " ,LVCFMT_LEFT, 100 );
      m_list.InsertColumn(
1 , " 年龄 " ,LVCFMT_LEFT, 100 );
    m_list.InsertColumn(
2 , " 妻子的数目 " ,LVCFMT_LEFT, 100 );
  
// 为listctrl添加三个item
    m_list.InsertItem( 0 , " 陈水扁 " , 0 );   
    m_list.SetItemText(
0 , 1 , " 66 " );        
    m_list.SetItemText(
0 , 2 , " 67 " );   

    m_list.InsertItem(
1 , " 游西堃 " , 0 );   
    m_list.SetItemText(
1 , 1 , " 85 " );         
    m_list.SetItemText(
1 , 2 , " 56 " );   
    
    m_list.InsertItem(
2 , " 布什 " , 0 );
    m_list.SetItemText(
2 , 1 , " 77 " );         
    m_list.SetItemText(
2 , 2 , " 26 " );
   
   
// 下面是为每一个item设置一个 itemdata
   
// 如果要用sortItems排序,这个是必须的。但是他的值不会影响到排序
    m_list.SetItemData( 0 ,(DWORD) " 垃圾 " );    
    m_list.SetItemData(
1 ,(DWORD) " 白痴 " );
    m_list.SetItemData(
2 ,(DWORD) " 傻叉 " );

然后,CListCtrl控件的 LVN_COLUMNCLICK 消息影射,并添加代码如下:

void CSortAView::OnColumnclickList1(NMHDR * pNMHDR, LRESULT * pResult)
... {
     NM_LISTVIEW
* pNMListView = (NM_LISTVIEW*)pNMHDR;
    
// TODO: Add your control notification handler code here
      MyData *tmpp=new MyData;
     tmpp
->listctrl=&m_list;
     tmpp
->isub=pNMListView->iSubItem;
    
int sortnum=(int)GetProp(m_list.GetSafeHwnd(),"SORT_COLUMN");
    
int sortasc=(int)GetProp(m_list.GetSafeHwnd(),"SORT_DIRECTION");
    
if(sortnum==pNMListView->iSubItem)...{
        sortasc
=(sortasc+1)%2;
        SetProp(m_list.GetSafeHwnd(),
"SORT_DIRECTION",(HANDLE)sortasc);
     }

     SetProp(m_list.GetSafeHwnd(),
"SORT_COLUMN",(HANDLE)pNMListView->iSubItem);
     tmpp
->seq=sortasc;
     m_list.SortItems(CompareFunc,(LPARAM)tmpp);




    
*pResult = 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值