http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx
以下未經說明,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_SHOWSELALWAYS5. 選中和取消選中一行
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. 得到另一個進程里的listctrl控件的item內容
http://www.codeproject.com/threads/int64_memsteal.asp
18. 選中listview中的item
Q131284: How To Select a Listview Item Programmaticallyhttp://support.microsoft.com/kb/131284/en-us
19. 如何在CListView中使用CListCtrl的派生類
http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/
20. listctrl的subitem添加圖標
m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
m_list.SetItem(..); //具體參數請參考msdn
21. 在CListCtrl顯示文件,并根據文件類型來顯示圖標
網上找到的代碼,share
BOOL CTest6Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
HIMAGELIST
himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO
sfi;
char cSysDir[MAX_PATH];
CString strBuf;
memset(cSysDir, 0, MAX_PATH);
GetWindowsDirectory(cSysDir, MAX_PATH);
strBuf =
cSysDir;
sprintf(cSysDir, "%s", strBuf.Left(strBuf.Find("\\")+1));
himlSmall = (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
himlLarge =
(HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX |
SHGFI_LARGEICON);
if (himlSmall &&
himlLarge)
{
::SendMessage(m_list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_SMALL,
(LPARAM)himlSmall);
::SendMessage(m_list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_NORMAL,
(LPARAM)himlLarge);
}
return TRUE; // return TRUE
unless you set the focus to a control
}
void
CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)
{
int nIcon = GetIconIndex(lpszFileName, FALSE,
FALSE);
CString strSize;
CFileFind filefind;
// get file size
if
(filefind.FindFile(lpszFileName))
{
filefind.FindNextFile();
strSize.Format("%d",
filefind.GetLength());
}
else
strSize = "0";
// split path and filename
CString strFileName = lpszFileName;
CString strPath;
int nPos = strFileName.ReverseFind('\\');
if (nPos
!= -1)
{
strPath =
strFileName.Left(nPos);
strFileName = strFileName.Mid(nPos +
1);
}
// insert to list
int
nItem = m_list.GetItemCount();
m_list.InsertItem(nItem,
strFileName, nIcon);
m_list.SetItemText(nItem, 1,
strSize);
m_list.SetItemText(nItem, 2,
strFileName.Right(3));
m_list.SetItemText(nItem, 3,
strPath);
}
int CTest6Dlg::GetIconIndex(LPCTSTR
lpszPath, BOOL bIsDir, BOOL bSelected)
{
SHFILEINFO
sfi;
memset(&sfi, 0, sizeof(sfi));
if
(bIsDir)
{
SHGetFileInfo(lpszPath,
FILE_ATTRIBUTE_DIRECTORY,
&sfi,
sizeof(sfi),
SHGFI_SMALLICON | SHGFI_SYSICONINDEX
|
SHGFI_USEFILEATTRIBUTES |(bSelected ?
SHGFI_OPENICON : 0));
return sfi.iIcon;
}
else
{
SHGetFileInfo (lpszPath,
FILE_ATTRIBUTE_NORMAL,
&sfi,
sizeof(sfi),
SHGFI_SMALLICON | SHGFI_SYSICONINDEX
|
SHGFI_USEFILEATTRIBUTES | (bSelected ?
SHGFI_OPENICON : 0));
return sfi.iIcon;
}
return -1;
}
22. listctrl內容進行大數據量更新時,避免閃爍
m_list.SetRedraw(FALSE);
//更新內容
m_list.SetRedraw(TRUE);
m_list.Invalidate();
m_list.UpdateWindow();
或者參考
23. listctrl排序
Q250614:How To Sort Items in a CListCtrl in Report View
http://support.microsoft.com/kb/250614/en-us
24. 在listctrl中選中某個item時動態改變其icon或bitmap
Q141834: How to change the icon or the bitmap of a CListCtrl item in Visual
C++
http://support.microsoft.com/kb/141834/en-us
How to change the icon or the bitmap of a
CListCtrl item in Visual C++
Article ID | : | 141834 |
Last Review | : | June 2, 2005 |
Revision | : | 3.0 |
SUMMARY
MORE INFORMATION
Sample Code
BEGIN_MESSAGE_MAP(CTestView, CView)
//{{AFX_MSG_MAP(CTestView)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_NOTIFY (LVN_GETDISPINFO, IDI_LIST, OnGetDispInfo)
END_MESSAGE_MAP()
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// m_pImage is a CTestView's member variable of type CImageList*
// create the CImageList with 16x15 images
m_pImage = new CImageList();
VERIFY (m_pImage->Create (16, 15, TRUE, 0, 1));
CBitmap bm;
// IDR_MAINFRAME is the toolbar bitmap in a default AppWizard
// project.
bm.LoadBitmap (IDR_MAINFRAME);
// This will automatically parse the bitmap into nine images.
m_pImage->Add (&bm, RGB (192, 192, 192));
// m_pList is CTestView's member variable of type CListCtrl*
// create the CListCtrl.
m_pList = new CListCtrl();
VERIFY (m_pList->Create (WS_VISIBLE | WS_CHILD | LVS_REPORT |
LVS_EDITLABELS, CRect (0, 0, 400, 400), this, IDI_LIST));
// Create column.
m_pList->InsertColumn (0, "Button Number", LVCFMT_LEFT, 100);
// Associate CImageList with CListCtrl.
m_pList->SetImageList (m_pImage, LVSIL_SMALL);
char szTemp[10];
for (int iCntr = 0; iCntr < 9; iCntr++)
{
wsprintf (szTemp, "%d", iCntr);
m_pList->InsertItem (LVIF_IMAGE | LVIF_TEXT,
iCntr, szTemp, 0, 0, I_IMAGECALLBACK, 0L);
}
return 0;
}
void CTestView::OnGetDispInfo (NMHDR* pnmhdr, LRESULT* pResult)
{
LV_DISPINFO* pdi = (LV_DISPINFO *) pnmhdr;
// Fill in the LV_ITEM structure with the image info.
// When an item is selected, the image is set to the first
// image (the new bitmap on the toolbar).
// When it is not selected, the image index is equal to the
// item number (that is, 0=new, 1=open, 2=save, and so on.)
if (LVIS_SELECTED == m_pList->GetItemState (pdi->item.iItem,
LVIS_SELECTED))
pdi->item.iImage = 0;
else
pdi->item.iImage = pdi->item.iItem;
}
CTestView::~CTestView()
{
// Clean up.
delete m_pImage;
delete m_pList;
}
25. 在添加item后,再InsertColumn()后導致整列數據移動的問題
Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift
http://support.microsoft.com/kb/151897/en-us
26. 關于listctrl第一列始終居左的問題
解決辦法:把第一列當一個虛列,從第二列開始插入列及數據,最后刪除第一列。
具體解釋參閱 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp
27. 鎖定column header的拖動
http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/
28. 如何隱藏clistctrl的列
把需隱藏的列的寬度設為0,然后檢測當該列為隱藏列時,用上面第27點的鎖定column 的拖動來實現
29. listctrl進行大數據量操作時,使用virtual list
http://www.microsoft.com/msj/archive/S2061.aspx
http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/
http://www.codeproject.com/listctrl/virtuallist.asp
30. 關于item只能顯示259個字符的問題
解決辦法:需要在item上放一個edit。
31. 響應在listctrl的column header上的鼠標右鍵單擊
Q125694: How To Find Out Which Listview Column Was Right-Clicked
http://support.microsoft.com/kb/125694/en-us
32. 類似于windows資源管理器的listview
Q234310: How to implement a ListView control that is similar to Windows
Explorer by using DirLV.exe
http://support.microsoft.com/kb/234310/en-us
33. 在ListCtrl中OnTimer只響應兩次的問題
Q200054:
PRB: OnTimer() Is Not Called Repeatedly for a List Control
http://support.microsoft.com/kb/200054/en-us
34. 以下為一些為實現各種自定義功能的listctrl派生類
(1) 拖放
http://www.codeproject.com/listctrl/dragtest.asp
在CListCtrl和CTreeCtrl間拖放
http://support.microsoft.com/kb/148738/en-us
(2) 多功能listctrl
支持subitem可編輯,圖標,radiobutton,checkbox,字符串改變顏色的類
http://www.codeproject.com/listctrl/quicklist.asp
支持排序,subitem可編輯,subitem圖標,subitem改變顏色的類
http://www.codeproject.com/listctrl/ReportControl.asp
(3) subitem中顯示超鏈接
http://www.codeproject.com/listctrl/CListCtrlLink.asp
(4) subitem的tooltip提示
http://www.codeproject.com/listctrl/ctooltiplistctrl.asp
(5) subitem中顯示進度條
http://www.codeproject.com/listctrl/ProgressListControl.asp
http://www.codeproject.com/listctrl/napster.asp
http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/
(6) 動態改變subitem的顏色和背景色
http://www.codeproject.com/listctrl/highlightlistctrl.asp
http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/
(7) 類vb屬性對話框
http://www.codeproject.com/listctrl/propertylistctrl.asp
http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/
http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/
(8) 選中subitem(只高亮選中的item)
http://www.codeproject.com/listctrl/SubItemSel.asp
http://www.codeproject.com/listctrl/ListSubItSel.asp
(9) 改變行高
http://www.codeproject.com/listctrl/changerowheight.asp
(10) 改變行顏色
http://www.codeproject.com/listctrl/coloredlistctrl.asp
(11) 可編輯subitem的listctrl
http://www.codeproject.com/listctrl/nirs2000.asp
http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp
(12) subitem可編輯,插入combobox,改變行顏色,subitem的tooltip提示
http://www.codeproject.com/listctrl/reusablelistcontrol.asp
(13) header
中允許多行字符串
http://www.codeproject.com/listctrl/headerctrlex.asp
(14) 插入combobox
http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/
(15) 添加背景圖片
http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/
http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/
http://www.vchelp.net/vchelp/archive.asp?type_id=9&class_id=1&cata_id=1&article_id=1088&search_term=
(16) 自適應寬度的listctrl
http://www.codeproject.com/useritems/AutosizeListCtrl.asp
(17) 改變ListCtrl高亮時的顏色(默認為藍色)
處理 NM_CUSTOMDRAW
http://www.codeproject.com/listctrl/lvcustomdraw.asp
(18) 改變header顏色
http://www.pocketpcdn.com/articles/hdr_color.html
原文地址 http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx