CListCtrl控制項使用方法總結

來源:互聯網
上載者:User
CListCtrl控制項使用方法總結

今天第一次用CListCtrl控制項,遇到不少問題,查了許多資料,現將用到的一些東西總結如下:

以下未經說明,listctrl預設view 風格為report

相關類及處理函數

MFC:CListCtrl類

SDK:以 “ListView_”開頭的一些宏。如 ListView_InsertColumn

1.
CListCtrl 風格

      LVS_ICON: 為每個item顯示大表徵圖
      LVS_SMALLICON: 為每個item顯示小表徵圖
     
LVS_LIST: 顯示一列帶有小表徵圖的item
      LVS_REPORT: 顯示item詳細資料

      直觀的理解:windows資源管理員,“查看”標籤下的“大表徵圖,小表徵圖,列表,詳細資料”

2. 設定listctrl 風格及擴充風格

      LONG lStyle;
      lStyle = GetWindowLong(m_list.m_hWnd,
GWL_STYLE);//擷取當前視窗style
      lStyle &= ~LVS_TYPEMASK;
//清除顯示方式位
      lStyle |= LVS_REPORT; //設定style
     
SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//設定style
 
      DWORD
dwStyle = m_list.GetExtendedStyle();
      dwStyle |=
LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl)
      dwStyle |=
LVS_EX_GRIDLINES;//網格線(只適用與report風格的listctrl)
      dwStyle |=
LVS_EX_CHECKBOXES;//item前產生checkbox控制項
      m_list.SetExtendedStyle(dwStyle);
//設定擴充風格
 
      註:listview的style請查閱msdn
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp

3. 插入資料

        m_list.InsertColumn( 0, "ID",
LVCFMT_LEFT, 40 );//插入列
      m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50
);
      int nRow = m_list.InsertItem(0, “11”);//插入行
     
m_list.SetItemText(nRow, 1, “jacky”);//設定資料

4.
一直選中item

   
選中style中的Show selection always,或者在上面第2點中設定LVS_SHOWSELALWAYS

5. 選中和取消選中一行

    int nIndex = 0;
    //選中
    m_list.SetItemState(nIndex,
LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
    //取消選中
   
m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

6. 得到listctrl中所有行的checkbox的狀態

      m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
      CString
str;
      for(int i=0; i<m_list.GetItemCount(); i++)
     
{
           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED ||
m_list.GetCheck(i))
           {
               
str.Format(_T("第%d行的checkbox為選中狀態"), i);
               
AfxMessageBox(str);
           }
      }

7. 得到listctrl中所有選中行的序號 


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

      方法二:
      POSITION pos =
m_list.GetFirstSelectedItemPosition();
      if (pos == NULL)
          
TRACE0("No items were selected!\n");
      else
      {
          
while (pos)
           {
                int nItem =
m_list.GetNextSelectedItem(pos);
                TRACE1("Item %d was
selected!\n", nItem);
                // you could do your own processing on
nItem here
           }
      }

8. 得到item的資訊

      TCHAR szBuf[1024];
      LVITEM lvi;
      lvi.iItem =
nItemIndex;
      lvi.iSubItem = 0;
      lvi.mask = LVIF_TEXT;
     
lvi.pszText = szBuf;
      lvi.cchTextMax = 1024;
     
m_list.GetItem(&lvi);

      關於得到設定item的狀態,還可以參考msdn文章
      Q173242: Use Masks to Set/Get Item
States in CListCtrl
               http://support.microsoft.com/kb/173242/en-us


 

9.
得到listctrl的所有列的header字串內容

      LVCOLUMN lvcol;
      char  str[256];
      int  
nColNum;
      CString  strColumnName[4];//假如有4列

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

10. 使listctrl中一項可見,即滾動捲軸

   
m_list.EnsureVisible(i, FALSE);

11. 得到listctrl列數

    int
nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();

12. 刪除所有列

      方法一:
         while ( m_list.DeleteColumn (0))
      
因為你刪除了第一列後,後面的列會依次向上移動。

      方法二:
      int nColumns = 4;
      for (int i=nColumns-1;
i>=0; i--)
          m_list.DeleteColumn (i);

13. 得到單擊的listctrl的行列號

      添加listctrl控制項的NM_CLICK訊息相應函數
      void
CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
     
{
           // 方法一:
           /*
           DWORD dwPos =
GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos)
);
  
           m_list.ScreenToClient(&point);
  
          
LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
          
lvinfo.flags = LVHT_ABOVE;
    
           int nItem =
m_list.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. 判斷是否點擊在listctrl的checkbox上

      添加listctrl控制項的NM_CLICK訊息相應函數
      void
CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
     
{
           DWORD dwPos = GetMessagePos();
           CPoint point(
LOWORD(dwPos), HIWORD(dwPos) );
  
          
m_list.ScreenToClient(&point);
  
           LVHITTESTINFO
lvinfo;
           lvinfo.pt = point;
           lvinfo.flags =
LVHT_ABOVE;
    
           UINT nFlag;
           int nItem =
m_list.HitTest(point, &nFlag);
           //判斷是否點在checkbox上
          
if(nFlag == LVHT_ONITEMSTATEICON)
           {
               
AfxMessageBox("點在listctrl的checkbox上");
           }
           *pResult =
0;
      }

15. 右鍵點擊listctrl的item快顯功能表

      添加listctrl控制項的NM_RCLICK訊息相應函數
      void
CTest6Dlg::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.
item切換焦點時(包括用鍵盤和滑鼠切換item時),狀態的一些變化順序

      添加listctrl控制項的LVN_ITEMCHANGED訊息相應函數
      void
CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
     
{
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
          
// TODO: Add your control notification handler code here
   
          
CString sTemp;
 
           if((pNMListView->uOldState &
LVIS_FOCUSED) == LVIS_FOCUSED &&
           
(pNMListView->uNewState & LVIS_FOCUSED) == 0)
          
{
                sTemp.Format("%d losted
focus",pNMListView->iItem);
           }
           else
if((pNMListView->uOldState & LVIS_FOCUSED) == 0
&&
               (pNMListView->uNewState & LVIS_FOCUSED) ==
LVIS_FOCUSED)
           {
                sTemp.Format("%d got
focus",pNMListView->iItem);
           }
 
          
if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED
&&
            (pNMListView->uNewState & LVIS_SELECTED) ==
0)
           {
                sTemp.Format("%d losted
selected",pNMListView->iItem);
           }
           else
if((pNMListView->uOldState & LVIS_SELECTED) == 0
&&
            (pNMListView->uNewState & LVIS_SELECTED) ==
LVIS_SELECTED)
           {
                sTemp.Format("%d got
selected",pNMListView->iItem);
           }
   
           *pResult
= 0;
      }

 

17.
改變選中行的顏色

首先是添加以下訊息

ON_NOTIFY( NM_CUSTOMDRAW, IDC_LIST1, OnDrawColorForMyList )  //為改變顏色添加的訊息

再添加類成員函數,就OK了:


//改變 m_List 控制項單行的顏色
void CSSDTDlg::OnDrawColorForMyList( NMHDR *pNmHdr, LRESULT *pResult )
{
 NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNmHdr );

    *pResult = CDRF_DODEFAULT;

 if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
 {
        *pResult = CDRF_NOTIFYITEMDRAW;
 }
    else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
 {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
 }
    else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )
 {
  COLORREF clrNewTextColor, clrNewBkColor;
        
  int    nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );

  //選中行顯示字型為紅色,否則為黑色
  if(m_item == nItem)  //設定為紅色
  {
   clrNewTextColor = RGB( 255, 0, 0 );
  }
  else  //設定為黑色
  {
   clrNewTextColor = RGB( 0, 0, 0 );
  }

  //設定背景色
  if( nItem%2 ==0 )
  {
   clrNewBkColor = RGB( 240, 240, 240 ); //偶數行背景色為灰色
  }
  else
  {
   clrNewBkColor = RGB( 255, 255, 255 ); //奇數行背景色為白色
  }

  pLVCD->clrText = clrNewTextColor;
  pLVCD->clrTextBk = clrNewBkColor;

        *pResult = CDRF_DODEFAULT;
 }
}

更多技巧參見以下連結:
http://blog.csdn.net/danforn/archive/2008/06/03/2508070.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.