天天看點

CListCtrl的使用

CListCtrl的使用

更新日期:2011-1-10

示例代碼:demo.zip (請不要使用下載下傳工具,否則可能出錯)

測試環境:VC6.0+WinXP

圖檔預覽:

CListCtrl 使用技巧:(這一篇文章寫得很好,極力推薦)

http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx

以下是網上收集的資料,都很不錯:(請不要使用下載下傳工具,否則可能出錯)

http://cid-3ba16e78a53d2d3d.office.live.com/self.aspx/VC/ClistCtrl-help.zip

基本樣式和擴張樣式

━━━━━━━━━━━━━━━━━━━━━━━━

(1)基本樣式

    LVS_ICON            大圖示顯示方式;

    LVS_LIST            清單顯示方式;

    LVS_SMALLICON        小圖示顯示方式;

    LVS_REPORT            以詳細資料即報告方式顯示;

    LVS_ALIGNLEFT        表項的大小圖示以左對齊方式顯示;

    LVS_ALIGNTOP        表項的大小圖示以頂對齊方式顯示;

    LVS_AUTOARRANGE        表項的大小圖示以自動排列方式顯示;

    LVS_EDITLABELS        設定表項文本可以編輯,父視窗必須設有LVN_ENDLABELEDIT風格;

    LVS_NOCOLUMNHEADER    在詳細資料方式時不顯示清單頭;

    LVS_NOLABELWRAP        以單行方式顯示圖示的文本項;

    LVS_NOSCROLL        用來屏蔽滾動條;

    LVS_NOSORTHEADER    清單頭不能用作按鈕功能;

    LVS_OWNERDRAWFIXED    在詳細清單方式時允許自繪視窗;

    LVS_SHAREIMAGELISTS    共享圖像清單方式,如果一個程式裡有兩個Listctrl同用一個HIMAGELIST,則其中一個摧毀不會影響另外一個,Specifies that the control does not take ownership of the image lists assigned to it (that is, it does not destroy the image lists when it is destroyed). This style enables the same image lists to be used with multiple list view controls.

    LVS_SHOWSELALWAYS    一直顯示被選中表項方式;

    LVS_SINGLESEL        在某一時刻隻能有一項被選中;

    LVS_SORTASCENDING    表項排序時是基于表項文本的升序方式;

    LVS_SORTDESCENDING    表項排序時是基于表項文本的降序方式;

    設定方法:

    LONG lStyle;

    lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //擷取目前視窗style

    lStyle &= ~LVS_TYPEMASK;                            //清除顯示方式位

    lStyle |=LVS_ICON  ;                                //設定style

    SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設定style

(2)擴充樣式,

    CListCtrl控件的擴充樣式,用SetExtendedStyle來改變

    LVS_EX_GRIDLINES        //繪制表格線(report風格時)

    LVS_EX_FULLROWSELECT    //選擇整行(report風格時)

    LVS_EX_SUBITEMIMAGES    //子項目圖示清單

    LVS_EX_CHECKBOXES        //帶複選框

    LVS_EX_TRACKSELECT        //自動換行

    LVS_EX_HEADERDRAGDROP    //報表頭可以拖拽

    LVS_EX_ONECLICKACTIVATE    //單擊激活

    LVS_EX_TWOCLICKACTIVATE    //輕按兩下激活

    LVS_EX_FLATSB            //扁平滾動條

    LVS_EX_REGIONAL

    LVS_EX_INFOTIP

    LVS_EX_UNDERLINEHOT

    LVS_EX_UNDERLINECOLD

    LVS_EX_MULTIWORKAREAS    //多工作區   

    設定方法:

    DWORD dwStyle = m_ListCtrl.GetExtendedStyle();    //擷取目前擴充樣式

    dwStyle |= LVS_EX_FULLROWSELECT;                //選中某行使整行高亮(report風格時)

    dwStyle |= LVS_EX_GRIDLINES;                    //網格線(report風格時)

    m_ListCtrl.SetExtendedStyle(dwStyle);            //設定擴充風格

初始化CListCtrl

━━━━━━━━━━━━━━━━━━━━━━━━

BOOL CDemoDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    //設定基本樣式

    LONG lStyle;

    lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //擷取目前視窗style

    lStyle |=LVS_REPORT            ;                        //以詳細資料即報告方式顯示;

    lStyle |=LVS_SHOWSELALWAYS    ;                        //一直顯示被選中表項方式;                   

    SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設定style

    //設定擴充樣式

    DWORD dwStyle = m_ListCtrl.GetExtendedStyle();    //擷取目前擴充樣式

    dwStyle |= LVS_EX_FULLROWSELECT;                //選中某行使整行高亮(report風格時)

    dwStyle |= LVS_EX_GRIDLINES;                    //網格線(report風格時)

    m_ListCtrl.SetExtendedStyle(dwStyle);            //設定擴充風格

    SHFILEINFO shFinfo;

    //擷取系統小圖示

    HIMAGELIST hImageListSmall=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO),

                        SHGFI_SYSICONINDEX|    SHGFI_SMALLICON);

    //擷取系統大圖示

     HIMAGELIST hImageListLarge=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO),

                        SHGFI_SYSICONINDEX|    SHGFI_ICON);

    m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListSmall),LVSIL_SMALL);

    m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListLarge),LVSIL_NORMAL);

//    ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL, (LPARAM)hImageList);

    //設定列

    m_ListCtrl.InsertColumn(0,   "第一列",   LVCFMT_LEFT,   150);  

    m_ListCtrl.InsertColumn(1,   "第二列",   LVCFMT_LEFT,   150);  

    m_ListCtrl.InsertColumn(2,   "第三列",   LVCFMT_LEFT,   150);  

    //添加c盤目錄到CListCtrl

    EnumFiles("c:",m_ListCtrl);

    //添加資料

    CString strData[3][3] =

    {

        { _T("Washington"), _T("George"), _T("1789-1797") },

        { _T("Adams"), _T("John"), _T("1797-1801") },

        { _T("Jefferson"), _T("Thomas"), _T("1801-1809") }

    };

    for (int i=0; i<3; i++)

    {

        m_ListCtrl.InsertItem(i, strData[i][0]);

        m_ListCtrl.SetItemText(i, 1, strData[i][1]);

        m_ListCtrl.SetItemText(i, 2, strData[i][2]);

        m_ListCtrl.SetItemData(i, i);

    }

    return TRUE;  // return TRUE  unless you set the focus to a control

}

以下展示4種視圖間的切換:

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnRadio1()

{

    LONG lStyle;

    lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //擷取目前視窗style

    lStyle &= ~LVS_TYPEMASK;                            //清除顯示方式位

    lStyle |=LVS_ICON  ;                                //設定style

    SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設定style

}

void CDemoDlg::OnRadio2()

{

    LONG lStyle;

    lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //擷取目前視窗style

    lStyle &= ~LVS_TYPEMASK;                            //清除顯示方式位

    lStyle |=LVS_LIST  ;                                //修改style

    SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設定style

}

void CDemoDlg::OnRadio3()

{

    //另外一種簡單的方法

    m_ListCtrl.ModifyStyle(LVS_TYPEMASK,LVS_SMALLICON);

}

void CDemoDlg::OnRadio4()

{

    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

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton1()

{

    //插入一行資料,方法一

    int nRow = m_ListCtrl.InsertItem(2,_T("text1"),0);    //參數(行數,标題,圖示索引)

    m_ListCtrl.SetItemText(nRow, 1, _T("text2"));        //參數(行數,此行的哪一列,文本)

    m_ListCtrl.SetItemText(nRow, 2, _T("text3"));        //參數(行數,此行的哪一列,文本)

    //插入一行資料,方法二

    LVITEM lvi = {0};                //定義一個資料項

    lvi.mask = LVIF_TEXT ;            //标志位 文本

    lvi.iItem = 3 ;                    //此項是3行,可修改為想要插入的行

    lvi.iSubItem = 0;                //此項是第幾列的資料               

    lvi.iImage =1;                    //第幾個圖示

    lvi.pszText =_T("jacky_qiu");    //文本

    m_ListCtrl.InsertItem(&lvi);                   

//    ::SendMessage(m_ListCtrl.m_hWnd, LVM_INSERTITEM, 0,(LPARAM)&lvi);

    //當插入item後調用SetColumnWidth可以自動變寬度大小

    m_ListCtrl.SetColumnWidth ( 0, LVSCW_AUTOSIZE_USEHEADER );

    m_ListCtrl.SetColumnWidth ( 1, LVSCW_AUTOSIZE_USEHEADER );

    m_ListCtrl.SetColumnWidth ( 2, LVSCW_AUTOSIZE_USEHEADER );

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton2()

{

    //修改某行某列的資料   

    LVITEM lvi = {0};            //定義一個資料項

    lvi.mask = LVIF_TEXT ;        //标志位 (指明需要修改什麼)

    lvi.iItem = 2 ;                //需要修改的項的索引

    lvi.iSubItem = 0;            //此項是第幾列的資料               

    lvi.iImage =1;                //第幾個圖示

    lvi.pszText =_T("修改");    //修改的文本

    //mfc

    m_ListCtrl.SetItem(&lvi);    //修改這一項,此項一定要存在

    //win32 api

    ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, NULL, (LPARAM)&lvi);

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton3()

{

    m_ListCtrl.DeleteItem(2);

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton6()

{

    //删除選中的多行

    POSITION  sSelPos = NULL;

    int nSelItem;

    while(sSelPos = m_ListCtrl.GetFirstSelectedItemPosition())

    {

        nSelItem = m_ListCtrl.GetNextSelectedItem(sSelPos);

        if(nSelItem >= 0 && nSelItem<m_ListCtrl.GetItemCount())

            m_ListCtrl.DeleteItem(nSelItem);

    }

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton5()

{

    //獲得選中的行(選中多行)

    POSITION pos=m_ListCtrl.GetFirstSelectedItemPosition();  

    if(pos!=   NULL)  

    {

        while (pos)

        {

            int nItem=m_ListCtrl.GetNextSelectedItem(pos); 

            trace("選中了",nItem);

        }

    }

    //擷取選中的多個項;

    int SelectItem=-1;

    while(-1!=(SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,SelectItem,MAKELPARAM(LVNI_SELECTED,0))))

    {

        trace("選中了:",SelectItem);

    }   

    //判斷是否一項也沒有選中

    if( -1!=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0)))

    {

        trace("選中了至少一項");

    }

    else

    {

        trace("沒有選中一項");

    }

    //如果ListCtrl是單選的,就用這種方式判斷選中的項

    SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0));

    if (SelectItem!=-1)

    {

        //get the item

        TCHAR szBuf[1024];

        LVITEM lvi;

        lvi.iItem = SelectItem;

        lvi.pszText = szBuf;

        lvi.cchTextMax = sizeof(szBuf)/sizeof(TCHAR);

        lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_DI_SETITEM;

        //第一列

        lvi.iSubItem = 0;

        ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi);

        trace(SelectItem,lvi.iSubItem,szBuf);

        //第二列

        lvi.iSubItem = 1;

        ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi);

        trace(SelectItem,lvi.iSubItem,szBuf);

        {

            TCHAR szBuf[1024];

            LVITEM lvi;

            lvi.pszText = szBuf;

            lvi.cchTextMax =sizeof(szBuf)/sizeof(TCHAR);

            lvi.iSubItem =0;

            lvi.mask = LVIF_TEXT;

            int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0);

            for(int i=0; i<count; i++)

            {

                ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)&lvi);

                trace(SelectItem,lvi.iSubItem,lvi.pszText);

            }

        }

        {

            int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0);

            for(int i=0; i<count; i++)

            {

                TCHAR szBuf[MAX_PATH];

                m_ListCtrl.GetItemText(i,0,szBuf,sizeof(szBuf)/sizeof(TCHAR));

                trace(szBuf);

            }

        }

    }

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnFind()

{

    //尋找一個item

    LVFINDINFO FindInfo;

    FindInfo.flags = LVFI_STRING ;  

    FindInfo.psz ="windows";

//    int nItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_FINDITEM,-1,(LPARAM)&FindInfo);

    int nItem=m_ListCtrl.FindItem(&FindInfo);

    if (nItem!=-1)

    {

        tracef("找到 %s,在 %d 行",FindInfo.psz,nItem);

    }

    else

    {

        tracef("找不到  %s ",FindInfo.psz);

    }

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton7()

{

    //獲得一項的圖示

    LVITEM lvi={0};

    lvi.iItem = 6;            //擷取第6項

    lvi.mask =LVIF_IMAGE;

    m_ListCtrl.GetItem(&lvi);

    tracef("image index : %d",lvi.iImage);

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton8()

{

    //需要設定dwStyle |= LVS_SHOWSELALWAYS;

    //當List control獲得焦點時 才會高亮度成藍色的,

    //如果List control沒有焦點,選中的項隻是灰色的

    //選中一個item,方法一

    m_ListCtrl.SetItemState(1,LVIS_SELECTED,LVIS_SELECTED);

    //選中一個item,方法二

    LVITEM lviItem;

    lviItem.stateMask=LVIS_SELECTED ;

    lviItem.state=LVIS_SELECTED;

    ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 2,(LPARAM) &lviItem);

    //選中一個item,方法三

    LVITEM lvi={0};

    lvi.iItem = 3;

    lvi.mask = LVIF_STATE;

    lvi.stateMask=LVIS_SELECTED  ;

    lvi.state=LVIS_SELECTED;

    ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi);

    {

        //取消選中第5項目,方法一

        m_ListCtrl.SetItemState(5,0,LVIS_SELECTED);

        //取消選中第4項目,方法二

        LVITEM lviItem;

        lviItem.stateMask=LVIS_SELECTED ;

        lviItem.state=0;

        ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 4,(LPARAM) &lviItem);

        //取消選中第6項目,方法三

        LVITEM lvi={0};

        lvi.iItem =6;

        lvi.mask = LVIF_STATE;

        lvi.stateMask=LVIS_SELECTED  ;

        lvi.state=0;

        ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi);

    }   

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton13()

{

    //擷取第2行的選中狀态,方法一

    LVITEM lvi={0};

    lvi.iItem = 2;

    lvi.mask = LVIF_STATE;

    lvi.stateMask=LVIS_SELECTED  ;    //lvi.mask 必須指定LVIF_STATE

//    ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM) &lvi);

    m_ListCtrl.GetItem(&lvi);

    if (lvi.state|LVIS_SELECTED==1)

    {

        trace("第2行 select");   

    }

    else

    {

        trace("第2行 no select");

    }

    //擷取第3行的選中狀态,方法二

    int state=(int)::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMSTATE,3,(LPARAM) LVIS_SELECTED);

    if (state|LVIS_SELECTED==1)

    {

        trace("第3行 select");   

    }

    else

    {

        trace("第3行 no select");   

    }

}

━━━━━━━━━━━━━━━━━━━━━━━━

//滑鼠點選

void CDemoDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)

{

    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

    if(pNMListView->iItem != -1)    //假如沒有選中一項

    {

        tracef("單擊的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem);

    }

    *pResult = 0;

}

void CDemoDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)

{

    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

    if(pNMListView->iItem != -1)    //假如選中一項

    {

        tracef("輕按兩下的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem);

    }

    *pResult = 0;

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton10()

{

    RECT ItemRect;

//    ItemRect.left=LVIR_LABEL   ;    //Returns the bounding rectangle of the item text.

//    ItemRect.left=LVIR_BOUNDS  ;    //Returns the bounding rectangle of the entire item, including the icon and label.

//    ItemRect.left=LVIR_ICON     ;    //Returns the bounding rectangle of the icon or small icon.

    ItemRect.left=LVIR_SELECTBOUNDS;//Returns the union of the LVIR_ICON and LVIR_LABEL rectangles, but excludes columns in details view.

    ::SendMessage(m_ListCtrl.m_hWnd,  LVM_GETITEMRECT , 1,(LPARAM)&ItemRect);

    HeightLightRect(m_ListCtrl.m_hWnd,ItemRect,true);

    trace(ItemRect);

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton11()

{

    m_ListCtrl.SetBkColor(RGB(200, 200, 200));     //設定背景顔色

    m_ListCtrl.SetTextBkColor(RGB(200, 200, 200)); //設定文本背景顔色

    m_ListCtrl.SetTextColor(RGB(10, 10, 80));      //設定文本顔色

    m_ListCtrl.Update(0);

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnButton15()

{

    //使某項可見,(出現在視窗裡)

//    m_ListCtrl.EnsureVisible(1,FALSE);   

    ::SendMessage(m_ListCtrl.m_hWnd, LVM_ENSUREVISIBLE, 10,(LPARAM) false);

    m_ListCtrl.SetItemState(10,LVIS_SELECTED,LVIS_SELECTED); //選中

}

━━━━━━━━━━━━━━━━━━━━━━━━

void CDemoDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)

{

    UINT nFlag;

    CPoint point;

    GetCursorPos(&point);

    m_ListCtrl.ScreenToClient(&point);

    int nItem = m_ListCtrl.HitTest(point, &nFlag);

    if (nItem >= 0)

        m_ListCtrl.EditLabel(nItem);

    *pResult = 0;

}

//編輯後修改文本

void CDemoDlg::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult)

{

    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

    LVITEMA item = pDispInfo->item;

    CString str = item.pszText;

    str.TrimLeft();

    str.TrimRight();

    if (str.GetLength() > 0)   

        m_ListCtrl.SetItemText(item.iItem,item.iSubItem,item.pszText);

    *pResult = 0;

}