赞
踩
作者:黎伟鑫
一 、前言:
Listview,即列表框控件。它在应用程序中的使用率很高,在windows中也经常见到,如其四种常见的式样,分别为显示大图标,小目标,含有图标的多列列表,含有列标头的列表。我们也经常见到它的一些扩展功能,例如我们在资源管理器中的文件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件按大小排序;单机日期,则按文件日期进行排序等。
它的诸多功能增强了应用程序的可用性,使操作更直观、方便。很多朋友在该控件的使用会遇到各种问题,现将其常用功能做了一下汇总整理,因为篇幅较长,分为三篇连载,前面两篇为《Listview控件使用技巧大汇总 连载(一)》和《Listview控件使用技巧大汇总 连载(二)》下面介绍为其第三部分,希望对读者有所帮助。
在整理过程中感谢网络上各位朋友提供的建议和帮助,感谢身边朋友的理解和陪伴。因为没有你们的支持可能没有耐心完成相关的汇总整理。
CListView中内置了CListCtrl,所以对CListView的操作实际上就是对内置CListCtrl的操作。下面代码例子中默认view 风格为report,相关类及处理函数为---MFC:CListCtrl类和SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn。
二 、高级级用法:
BOOL C6Dlg::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 C6Dlg::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 C6Dlg::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; }
2.2. listctrl排序
示例代码如下:
void CMyView::OnInitialUpdate() { CFormView::OnInitialUpdate(); m_listCtrl.InsertColumn(0, "Western States", LVCFMT_LEFT, 150); LV_ITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF_TEXT | LVIF_STATE; lvItem.iItem = 0; lvItem.state = LVIS_CUT | LVIS_SELECTED; lvItem.pszText = "Washington"; m_listCtrl.InsertItem(&lvItem); // initially selected lvItem.iItem = 1; lvItem.state = LVIS_CUT | LVIS_SELECTED; lvItem.pszText = "Arizona"; m_listCtrl.InsertItem(&lvItem); // initially selected lvItem.iItem = 2; lvItem.state = LVIS_CUT; lvItem.pszText = "Alaska"; m_listCtrl.InsertItem(&lvItem); lvItem.iItem = 3; lvItem.state = LVIS_CUT; lvItem.pszText = "California"; m_listCtrl.InsertItem(&lvItem); lvItem.iItem = 4; lvItem.state = LVIS_CUT; lvItem.pszText = "Nevada"; m_listCtrl.InsertItem(&lvItem); UINT nState; CString strText; int iItem = -1; // as long as GetNextItem found an item... while ((iItem = m_listCtrl.GetNextItem(iItem, LVNI_ALL)) > -1 ) { // get item string strText = m_listCtrl.GetItemText(iItem, 0); // show initial state of flags nState = m_listCtrl.GetItemState(iItem, LVIS_SELECTED | LVIS_CUT); TRACE("%s state flag is %0x\n", strText, nState); // Get only LVIS_SELECTED flag // note that LVIS_CUT is not returned in nState nState = m_listCtrl.GetItemState(iItem, LVIS_SELECTED); // select states beginning with 'A' if (strText[0] == 'A' && !nState) { TRACE("%s needed to be selected\n", strText); m_listCtrl.SetItemState(iItem, LVIS_SELECTED, // nState LVIS_SELECTED); // nMask // deselect states that don't begin with 'A' } else if (strText[0] != 'A' && nState) { TRACE("%s needed to be deselected\n", strText); m_listCtrl.SetItemState(iItem, 0, // nState LVIS_SELECTED); // nMask } // show new flags if modified, note that LVIS_CUT wasn't affected nState = m_listCtrl.GetItemState(iItem, LVIS_SELECTED | LVIS_CUT); TRACE("%s state flag is now %0x\n", strText, nState); } } // 排序用的比较函数 static int CALLBACK MyCompareProc(LPARAMlParam1, LPARAMlParam2, LPARAMlParamSort) { CString &lp1 = *((CString *)lParam1); CString &lp2 = *((CString *)lParam2); int &sort = *(int *)lParamSort; if (sort == 0) { returnlp1.CompareNoCase(lp2); } else { returnlp2.CompareNoCase(lp1); } } //要处理的事件 ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, &CDlg::OnLvnColumnclickList1) //处理代码 voidCDlg::OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEWpNMLV = reinterpret_cast(pNMHDR); intLength = m_ListCtrl.GetItemCount(); CArray ItemData; ItemData.SetSize(Length); for (inti = 0; i < Length; i++) { ItemData[i] = m_ListCtrl.GetItemText(i,pNMLV->iSubItem); m_ListCtrl.SetItemData(i,(DWORD_PTR)&ItemData[i]);//设置排序关键字 } staticintsort = 0; staticintSubItem = 0; if (SubItem != pNMLV->iSubItem) { sort = 0; SubItem = pNMLV->iSubItem; } else { if (sort == 0) { sort = 1; } else { sort = 0; } } m_ListCtrl.SortItems(MyCompareProc,(DWORD_PTR)&sort);//排序 *pResult = 0; }
列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属性值。MFC中使用CListCtrl类来封装列表控件的各种操作。通过调用 BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );创建一个窗口,dwStyle中可以使用以下一些列表控件的专用风格:
LVS_ICON LVS_SMALLICON LVS_LIST LVS_REPORT 这四种风格决定控件的外观,同时只可以选择其中一种,分别对应:大图标显示,小图标显示,列表显示,详细报表显示
LVS_EDITLABELS 结点的显示字符可以被编辑,对于报表风格来讲可编辑的只为第一列。
LVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点
LVS_SINGLESEL 同时只能选中列表中一项
首先你需要设置列表控件所使用的ImageList,如果你使用大图标显示风格,你就需要以如下形式调用: CImageList* SetImageList( CImageList* pImageList, LVSIL_NORMAL); 如果使用其它三种风格显示而不想显示图标你可以不进行任何设置,否则需要以如下形式调用: CImageList* SetImageList( CImageList* pImageList, LVSIL_SMALL);
通过调用int InsertItem( int nItem, LPCTSTR lpszItem );可以在列表控件中nItem指明位置插入一项,lpszItem为显示字符。除LVS_REPORT风格外其他三种风格都只需要直接调用 InsertItem就可以了,但如果使用报表风格就必须先设置列表控件中的列信息。
通过调用int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem);可以插入列。iCol为列的位置,从零开始,lpszColumnHeading为显示的列名,nFormat为显示对齐方式, nWidth为显示宽度,nSubItem为分配给该列的列索引。
m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//设置ImageList m_list.InsertColumn(0,"Col 1",LVCFMT_LEFT,300,0);//设置列 m_list.InsertColumn(1,"Col 2",LVCFMT_LEFT,300,1); m_list.InsertColumn(2,"Col 3",LVCFMT_LEFT,300,2); m_list.InsertItem(0,"Item 1_1");//插入行 m_list.SetItemText(0,1,"Item 1_2");//设置该行的不同列的显示字符 m_list.SetItemText(0,2,"Item 1_3");
此外CListCtrl还提供了一些函数用于得到/修改控件的状态。 COLORREF GetTextColor( )/BOOL SetTextColor( COLORREF cr );用于得到/设置显示的字符颜色。 COLORREF GetTextBkColor( )/BOOL SetTextBkColor( COLORREF cr );用于得到/设置显示的背景颜色。 void SetItemCount( int iCount );用于得到添加进列表中项的数量。 BOOL DeleteItem(int nItem);用于删除某一项,BOOL DeleteAllItems( );将删除所有项。 BOOL SetBkImage(HBITMAP hbm, BOOL fTile , int xOffsetPercent, int yOffsetPercent);用于设置背景位图。 CString GetItemText( int nItem, int nSubItem );用于得到某项的显示字符。
列表控件的消息映射同样使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn ),wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型如同void OnXXXList(NMHDR* pNMHDR, LRESULT* pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于列表控件可能取值和对应的数据结构为:
LVN_BEGINLABELEDIT 在开始某项编辑字符时发送,所用结构:NMLVDISPINFO
LVN_ENDLABELEDIT 在结束某项编辑字符时发送,所用结构:NMLVDISPINFO
LVN_GETDISPINFO 在需要得到某项信息时发送,(如得到某项的显示字符)所用结构:NMLVDISPINFO
关于ON_NOTIFY有很多内容,将在以后的内容中进行详细讲解。
关于动态提供结点所显示的字符:首先你在项时需要指明lpszItem参数为: LPSTR_TEXTCALLBACK。在控件显示该结点时会通过发送TVN_GETDISPINFO来取得所需要的字符,在处理该消息时先将参数 pNMHDR转换为LPNMLVDISPINFO,然后填充其中item.pszText。通过item中的iItem,iSubItem可以知道当前显示的为那一项。下面的代码演示了这种方法:
char szOut[8][3]={"No.1","No.2","No.3"}; //添加结点 m_list.InsertItem(LPSTR_TEXTCALLBACK,...) m_list.InsertItem(LPSTR_TEXTCALLBACK,...) //处理消息 void CParentWnd::OnGetDispInfoList(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR; pLVDI->item.pszText=szOut[pTVDI->item.iItem];//通过iItem得到需要显示的字符在数组中的位置 *pResult = 0; }
关于编辑某项的显示字符:(在报表风格中只对第一列有效)首先需要设置列表控件的 LVS_EDITLABELS风格,在开始编辑时该控件将会发送LVN_BEGINLABELEDIT,你可以通过在处理函数中返回TRUE来取消接下来的编辑,在编辑完成后会发送LVN_ENDLABELEDIT,在处理该消息时需要将参数pNMHDR转换为LPNMLVDISPINFO,然后通过其中的item.pszText得到编辑后的字符,并重置显示字符。如果编辑在中途中取消该变量为NULL。下面的代码说明如何处理这些消息:
//处理消息 LVN_BEGINLABELEDIT void CParentWnd::OnBeginEditList(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR; if(pLVDI->item.iItem==0);//判断是否取消该操作 *pResult = 1; else *pResult = 0; } //处理消息 LVN_BEGINLABELEDIT void CParentWnd::OnBeginEditList(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR; if(pLVDI->item.pszText==NULL);//判断是否已经取消取消编辑 m_list.SetItemText(pLVDI->item.iItem,0,pLVDI->pszText);//重置显示字符 *pResult = 0; }
上面讲述的方法所进行的消息映射必须在父窗口中进行(同样WM_NOTIFY的所有消息都需要在父窗口中处理)。
如何得到当前选中项位置:在列表控件中没有一个类似于ListBox中GetCurSel()的函数,但是可以通过调用GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);得到选中项位置。
m_list.SetRedraw(FALSE); //更新内容 m_list.SetRedraw(TRUE); m_list.Invalidate(); m_list.UpdateWindow();
或者参考
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwnd.3a3a.setredraw.asp
2.4.在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
2.5.在添加item后,再InsertColumn()后导致整列数据移动的问题
Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift
http://support.microsoft.com/kb/151897/en-us
2.6.关于listctrl第一列始终居左的问题
解决办法:把第一列当一个虚列,从第二列开始插入列及数据,最后删除第一列。
2.7.锁定column header的拖动
http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/
2.8.如何隐藏clistctrl的列
把需隐藏的列的宽度设为0,然后检测当该列为隐藏列时,用上面第27点的锁定column 的拖动来实现
2.9.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
2.10.关于item只能显示259个字符的问题
解决办法:需要在item上放一个edit。
2.11.响应在listctrl的column header上的鼠标右键单击
Q125694: How To Find Out Which Listview Column Was Right-Clicked
http://support.microsoft.com/kb/125694/en-us
2.12.类似于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
2.13.在ListCtrl中OnTimer只响应两次的问题
Q200054:
PRB: OnTimer() Is Not Called Repeatedly for a List Control
http://support.microsoft.com/kb/200054/en-us
2.14.以下为一些为实现各种自定义功能的listctrl派生类
(1) 拖放
http://www.codeproject.com/listctrl
在CListCtrl和CTreeCtrl间拖放
http://support.microsoft.com/kb/148738/en-us
(2) 多功能listctrl
支持subitem可编辑,图标,radiobutton,checkbox,字符串改变颜色的类
http://www.codeproject.com/Articles/8112/CQuickList
支持排序,subitem可编辑,subitem图标,subitem改变颜色的类
http://www.codeproject.com/Articles/5560/Another-Report-List-Control
(3) subitem中显示超链接
http://www.codeproject.com/Articles/4821/CListCtrl-With-Web-Links
(4) subitem的tooltip提示
http://www.codeproject.com/Articles/1548/CToolTipListCtrl-A-CListCtrl-derived-class-providi
(5) subitem中显示进度条
http://www.codeproject.com/Articles/6813/List-Control-Extended-for-Progress-Control
http://www.codeproject.com/Articles/1342/Adding-progress-bars-to-a-list-control
http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/
(6) 动态改变subitem的颜色和背景色
http://www.codeproject.com/Articles/1316/Dynamically-Highlight-Elements-in-a-List-Control
http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/
(7) 类vb属性对话框
http://www.codeproject.com/Articles/614/An-Adaptable-Property-List-Control
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/Articles/8194/SubItem-Selection-in-List-Control
http://www.codeproject.com/Articles/9155/SubItem-Selection-in-List-Control
(9) 改变行高
http://www.codeproject.com/Articles/1401/Changing-Row-Height-in-an-owner-drawn-Control
(10) 改变行颜色
http://www.codeproject.com/Articles/12343/Alternate-Row-Colors-for-the-CListCtrl
(11) 可编辑subitem的listctrl
http://www.codeproject.com/Articles/1317/Editable-Table-Control
http://www.codeproject.com/Articles/1124/Editing-Sub-Items-in-List-Control
(12) subitem可编辑,插入combobox,改变行颜色,subitem的tooltip提示
http://www.codeproject.com/Articles/12344/A-Simple-Reusable-List-Control
(13) header 中允许多行字符串
http://www.codeproject.com/Articles/510/A-Multiline-Header-Control-Inside-a-CListCtrl
(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/
(16) 自适应宽度的listctrl
http://www.codeproject.com/Articles/11483/Let-Your-ListCtrl-Adjust-its-Column-Widths-Automat
(17) 改变ListCtrl高亮时的颜色(默认为蓝色)
处理 NM_CUSTOMDRAW
http://www.codeproject.com/Articles/79/Neat-Stuff-to-Do-in-List-Controls-Using-Custom-Dra
(18) 改变header颜色
http://www.pocketpcdn.com/articles/hdr_color.html
m_pCtrl = &this->GetListCtrl(); //获得指针 //CListCtrl样式改变 LONG lStyle; lStyle = GetWindowLong(m_pCtrl->m_hWnd, GWL_STYLE); //获取当前窗口style lStyle &= ~LVS_TYPEMASK; //清除显示方式 lStyle |= LVS_REPORT; //设置style为Report显示 SetWindowLong(m_pCtrl->m_hWnd, GWL_STYLE, lStyle); //CListCtrl扩展样式改变 DWORD dwStyle; dwStyle = m_pCtrl->GetStyle(); //取得样式 dwStyle |= LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT ; //添加样式 m_pCtrl->SetExtendedStyle(dwStyle); //重新设置
需要的样式(根据自己的需要的样式选择) LVS_ICON: 为每个item显示大图标 LVS_SMALLICON: 为每个item显示小图标 LVS_LIST: 显示一列带有小图标的item LVS_REPORT: 显示item详细资料 LVS_EX_FULLROWSELECT: 表示选中某行使整行高亮(只适用与report风格的CListCtrl) LVS_EX_GRIDLINES: 表示显示网格线(只适用与report风格的CListCtrl)
2.16.添加CListCtrl的记录
//插入列 m_pCtrl->InsertColumn(1,"第一列",LVCFMT_CENTER,47); //序号,标题,标题显示位置,列宽度 m_pCtrl->InsertColumn(2,"第二列",LVCFMT_CENTER,100); //写入数据 int nRow = m_list.InsertItem(0, “无用字符串”); //插入行 m_list.SetItemText(nRow, 1, “1111”); //设置数据 m_list.SetItemText(nRow, 2, “2222”); //设置数据
int n = -1; POSITION pos = m_pCtrl->GetFirstSelectedItemPosition(); //返回第一个选中的行位置 if (pos != NULL) { while (pos) { n = m_pCtrl->GetNextSelectedItem(pos); //返回下一个选中的行数(返回值从0开始) //做相应操作 } }
2.18. CListCtrl,CListView与LVN_ITEMCHANGED消息
若要在CListCtrl中行发生改变时得到通知,可以映射LVN_ITEMCHANGED消息。
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged) afx_msg void OnItemchanged(NMHDR* pNMHDR,LRESULT* pResult); // 行选择改变 void CMyListCtrl::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; ...您要进行的操作... *pResult = 0; }
void CRunListView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if(pNMListView->uChanged == LVIF_STATE) { if(pNMListView->uNewState) TRACE0("选择改变且有选中的行/r/n"); else TRACE0("选择改变且没有选中的行/r/n"); } else TRACE0("行改变(CListCtrl::SetItem)/r/n"); *pResult = 0; }
2.19.响应单击CListCtrl事件
//响应CMyListView的=NUM_CLICK消息 //直接用VC类向导生成后,不用再次添加声明和消息映射 //添加函数声明 afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult); //添加消息映射 ON_NOTIFY_REFLECT(NM_CLICK, OnClick) void CMyListView::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if(pNMListView->iItem != -1) { //值从0开始计算,无数据区不相应时间 //相应操作 } *pResult = 0; }
2.20.自绘ListCtrl类
示例如下:
//自绘CListCtrl类,重载虚函数DrawItem void CNewListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item ASSERT(lpDrawItemStruct->CtlType == ODT_LISTVIEW); CDC dc; dc.Attach(lpDrawItemStruct->hDC); ASSERT(NULL != dc.GetSafeHdc()); // Save these value to restore them when done drawing. COLORREF crOldTextColor = dc.GetTextColor(); COLORREF crOldBkColor = dc.GetBkColor(); // If this item is selected, set the background color // and the text color to appropriate values. Also, erase // rect by filling it with the background color. if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) { dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); dc.FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_HIGHLIGHT)); } else { if(lpDrawItemStruct->itemID%2) dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(128,128,128)); else dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,128,255)); } // If this item has the focus, draw a red frame around the // item's rect. if ((lpDrawItemStruct->itemAction | ODA_FOCUS) && (lpDrawItemStruct->itemState & ODS_FOCUS)) { CBrush br(RGB(0, 0, 128)); dc.FrameRect(&lpDrawItemStruct->rcItem, &br); } // Draw the text. CString strText(_T("")); CRect rcItem; for(int i=0; iGetItemCount(); i++) { strText = GetItemText(lpDrawItemStruct->itemID, i); GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem); rcItem.left += 5; dc.DrawText( strText, strText.GetLength(), &rcItem, DT_LEFT|DT_SINGLELINE|DT_VCENTER); } // Reset the background color and the text color back to their // original values. dc.SetTextColor(crOldTextColor); dc.SetBkColor(crOldBkColor); dc.Detach(); } // 调用 CNewListCtrl m_list; // 类的成员变量 #define IDC_LIST 0x1101 m_list.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL|LVS_OWNERDRAWFIXED, CRect(0, 0, 280, 280), this, IDC_LIST); m_list.ModifyStyle(0, LVS_REPORT|LVS_SINGLESEL); m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); m_list.InsertColumn(0, _T("VVV"), LVCFMT_LEFT, 100); m_list.InsertColumn(1, _T("CCC"), LVCFMT_LEFT, 100); CString strText(_T("")); for(int i=0; i<10; i++) { m_list.InsertItem(i, _T("")); strText.Format(_T("%d - Hello, Vckbase!"), i+1); m_list.SetItemText(i, 0, strText); strText.Format(_T("%d – All Is Well"), i+1); m_list.SetItemText(i, 1, strText); }
三、总结:
以上为该控件的高级用法,谢谢您的关注^_^。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。