动态创建script标签CListCtrl可以使用虚拟列表技术吗

求mfc大神帮助(或者对虚拟列表熟悉的都行)_c++吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:263,117贴子:
求mfc大神帮助(或者对虚拟列表熟悉的都行)收藏
我用虚拟列表显示数据,已经显示出的数据点击一行数据会变成没显示出的其他数据,向上滑动之前的数据也会变成其他没显示出来的数据求解决方法
上海达内c++一般需要4-8周,就可以完全掌握.上海c++的费用根据培训课时定,120天从入门到精通..
是列表控件?还是别的?列表控件的话不是要一个一个的加入进去么。
不知道虚拟列表的路过……真心没听过虚拟列表……
我觉得MSDN会是比较好的去处
很详细的 应该是你GETDISPINFO 消息回调没处理好造成的
CListCtrl控件的虚拟列表分页显示,要自己维护条目的状态信息。这东西我做过,显示几万条数据没问题。下面是我一个程序的相关的部分代码:以1024条为一页(1屏+前后余量缓冲)void CXXXView::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult) {
NMLVDISPINFO *pDispInfo = reinterpret_cast&NMLVDISPINFO*&(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
LV_ITEM* pItem= &(pDispInfo)-&
pItem-&mask |= LVIF_STATE;
pItem-&stateMask = LVIS_STATEIMAGEMASK;
int iItemIndx= pItem-&iI
if (pItem-&mask & LVIF_TEXT)
if(GetDocument()-&m_intLB == 0)
long page = long(iItemIndx/1024);
long index = iItemIndx - page * 1024;
GetDocument()-&SetCachePatient(page);
patient=GetDocument()-&m_array_Patient.GetData();
switch(pItem-&iSubItem)
temp.Format(_T("%d"), (patient+index)-&Depcode);
lstrcpy(pItem-&pszText, temp);
lstrcpy(pItem-&pszText, (patient+index)-&Phone21);
if((patient+index)-&ZT)
lstrcpy(pItem-&pszText, _T("死亡"));
lstrcpy(pItem-&pszText, _T("活着"));
else if(GetDocument()-&m_intLB == 1)
long page = long(iItemIndx/1024);
long index = iItemIndx - page * 1024;
GetDocument()-&SetCacheZhuyuan(page);
Zhuyuan* zhuyuan=GetDocument()-&m_array_Zhuyuan.GetData();
switch(pItem-&iSubItem)
temp.Format(_T("%d"), (zhuyuan+index)-&Depcode);
lstrcpy(pItem-&pszText, temp);
if((zhuyuan+index)-&Zhiliao)
lstrcpy(pItem-&pszText, _T("√"));
if((zhuyuan+index)-&Other)
lstrcpy(pItem-&pszText, _T("√"));
if((zhuyuan+index)-&Unknown)
lstrcpy(pItem-&pszText, _T("√"));
lstrcpy(pItem-&pszText, (zhuyuan+index)-&Beizhu);
else if(GetDocument()-&m_intLB == 2)
long page = long(iItemIndx/1024);
long index = iItemIndx - page * 1024;
GetDocument()-&SetCacheShuifang(page);
Shuifang* shuifang=GetDocument()-&m_array_Shuifang.GetData();
switch(pItem-&iSubItem)
temp.Format(_T("%d"), (shuifang+index)-&Depcode);
lstrcpy(pItem-&pszText, temp);
lstrcpy(pItem-&pszText, (shuifang+index)-&Name);
lstrcpy(pItem-&pszText, (shuifang+index)-&Receive);
else if(GetDocument()-&m_intLB == 3)
long page = long(iItemIndx/1024);
long index = iItemIndx - page * 1024;
GetDocument()-&SetCacheUseShuifang(page);
UseShuifang* useshuifang=GetDocument()-&m_array_UseShuifang.GetData();
switch(pItem-&iSubItem)
temp.Format(_T("%d"), (useshuifang+index)-&Depcode);
lstrcpy(pItem-&pszText, temp);
lstrcpy(pItem-&pszText, (useshuifang+index)-&Name);
if((useshuifang+index)-&ZT)
lstrcpy(pItem-&pszText, _T("死亡"));
lstrcpy(pItem-&pszText, _T("活着"));
else if(GetDocument()-&m_intLB == 4)
long page = long(iItemIndx/1024);
long index = iItemIndx - page * 1024;
GetDocument()-&SetCacheJieyue(page);
Jieyue* jieyue=GetDocument()-&m_array_Jieyue.GetData();
switch(pItem-&iSubItem)
temp.Format(_T("%d"), (jieyue+index)-&Depcode);
lstrcpy(pItem-&pszText, temp);
lstrcpy(pItem-&pszText, (jieyue+index)-&Name);
lstrcpy(pItem-&pszText, (jieyue+index)-&Outdate);
lstrcpy(pItem-&pszText, (jieyue+index)-&Indate);
lstrcpy(pItem-&pszText, (jieyue+index)-&Docname);
if (pItem-&mask & LVIF_STATE)
CodeCheck* codecheck = GetDocument()-&m_array_CodeCheck.GetData();
if((codecheck+iItemIndx)-&Check)
pItem-&state = INDEXTOSTATEIMAGEMASK(2);
pItem-&state = INDEXTOSTATEIMAGEMASK(1);
*pResult = 0; }
void CXXXView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) {
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast&LPNMITEMACTIVATE&(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
long item = GetListCtrl().HitTest(pNMItemActivate-&ptAction, &uFlags);
if(item != -1)
if( uFlags
== LVHT_ONITEMSTATEICON)
(GetDocument()-&m_array_CodeCheck.GetData() + item)-&Check = !(GetDocument()-&m_array_CodeCheck.GetData() + item)-&C
GetListCtrl().RedrawItems(item, item);
*pResult = 0; }
还要先设置listCtrl的条目总量,更新数据前最好锁定刷新,更新完后再刷新显示。void CPatientView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/) {
// TODO: 在此添加专用代码和/或调用基类
CListCtrl* m_listC
m_listCtrl = &(this-&GetListCtrl());
m_listCtrl-&DeleteAllItems();
m_listCtrl-&LockWindowUpdate();
m_listCtrl-&SetItemCountEx(GetDocument()-&m_CountNum, LVSICF_NOINVALIDATEALL);
m_listCtrl-&UnlockWindowUpdate(); }
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或虚拟列表控件CListCtrl
一、什么是虚拟列表控件
虚拟列表控件是指带有LVS_OWNERDATA风格的列表控件。
二、为什么使用虚拟列表控件
我们知道,通常使用列表控件CListCtrl,需要调用InsertItem把要显示的数据插入列表中,之后我们就不必关心数据在哪里了,这是因为控件自己开辟了内存空间来保存这些数据。现在假设我们要显示一个数据库,里面的信息量很大,有几十万条记录。通常有两种方法解决这个问题:1是仅仅在ListCtrl中插入少量的数据,比如100个,然后通过[上一页][下一页]两个按钮进行控制,某一时刻显示的只是从xxx到xxx+100之间的记录。2是把所有数据全部插入到ListCtrl中,然后让用户通过滚动来查看数据。无疑,很多用户喜欢采用第二种方式,特别是对于已经排序的数据,用户只需用键盘输入某行的开头字符,就可以快速定位到某一行。但是,如果这样做,InsertItem插入数据的过程将是很漫长的,而且用户会看到ListCtrl刷新速度也很慢,而且所有数据都位于内存中消耗了大量的内存,当数据多达上万以后几乎是不能忍受的。
为此,mfc特别提供了虚拟列表的支持。一个虚拟列表看起来和普通的ListCtrl一样,但是不用通过InsertItem来插入数据,它仅仅知道自己应该显示多少数据。但是它如何知道要显示什么数据呢?秘密就在于当列表控件需要显示某个数据的时候,它向父窗口要。假设这个列表控件包含100个元素,第10到20个元素(行)是可见的。当列表控件重画的时候 ,它首先请求父窗口给它第10个元素的数据,父窗口收到请求以后,把数据信息填充到列表提供的一个结构中,列表就可以用来显示了,显示第10个数据后,列表会继续请求下一个数据。
在虚拟的样式下,ListCtrl可以支持多达DWORD个数据项。(缺省的listctrl控件最多支持int个数据项)。但是,虚拟列表的最大优点不在于此,而是它仅仅需要在内存中保持极少量的数据,从而加快了显示的速度。所以,在使用列表控件显示一个很大的数据库的情况下,采用虚拟列表最好不过了。
不仅CListCtrl提供虚拟列表的功能, MFC的CListView类也有同样的功能。
三、虚拟列表控件的消息
虚拟列表总共发送三个消息给父窗口:当它需要数据的时候,它发送LVN_GETDISPINFO消息。这是最重要的消息。当用户试图查找某个元素的时候,它发送LVN_ODFINDITEM消息;还有一个消息是LVN_ODCACHEHINT,用来缓冲数据,基本上很少用到这个消息。
虚拟列表控件使用起来非常简单。它总共只有三个相关的消息,如果你直接使用CListCtrl,应该在对话框中响应这三个消息。如果你使用CListCtrl派生类,可以在派生类中响应这三个消息的反射消息。这三个消息分别是:
& (1)LVN_GETDISPINFO 控件请求某个数据& (2)LVN_ODFINDITEM& 查找某个数据& (3)LVN_ODCACHEHINT 缓冲某一部分数据
我们必须响应的消息是(1),多数情况下要响应(2),极少数的情况下需要响应(3)
四、如何使用虚拟列表控件
1、首先要创建控件,创建一个虚拟列表和创建一个正常的 CListCtrl差不多。先在资源编辑器里面添加一个list control资源。然后选中"Owner data"属性,然后给它捆绑一个CListCtrl变量。添加列,添加imagelist等都和使用正常的listctrl一样。
2、给虚拟列表添加元素。假设 m_list 是这个列表的控制变量。通常的情况下这样添加数据:
m_list.InsertItem(0, _T("Hello world"));
但是对于虚拟列表,不能这么做。只需告诉列表有多少个数据:
//总共显示100行m_list.SetItemCount(100);
3、处理它的通知消息。
五、如何响应虚拟列表的消息
1、处理 LVN_GETDISPINFO 通知消息
当虚拟列表控件需要某个数据的时候,它给父窗口发送一个 LVN_GETDISPINFO通知消息,表示请求某个数据。因此列表的所有者窗口(或者它自己)必须处理这个消息。例如派生类的情况 (CMyListCtrl是一个虚拟列表类对象):
//这里处理的是反射消息BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)&& //{{AFX_MSG_MAP(CMyListCtrl)&& ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)&& //}}AFX_MSG_MAPEND_MESSAGE_MAP()
在LVN_GETDISPINFO的处理函数中,必须首先检查列表请求的是什么数据,可能的值包括:
(1)LVIF_TEXT&& 必须填充 pszText(2)LVIF_IMAGE& 必须填充 iImage&(3)LVIF_INDENT 必须填充 iIndent(4)LVIF_PARAM& 必须填充 lParam&(5)LVIF_STATE& 必须填充 state
根据它的请求,填充所需的数据即可。
//================= 例子代码=====================================
下面的给出一个例子,填充的是列表所需的某个数据项的文字以及图像信息:
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;LV_ITEM* pItem= &(pDispInfo)-&
int iItemIndx= pItem-&iI
if (pItem-&mask & LVIF_TEXT) //字符串缓冲区有效{&&& switch(pItem-&iSubItem){&&&&&&& case 0: //填充数据项的名字&&&&&&&&&&& lstrcpy(pItem-&pszText,m_Items[iItemIndx].m_strItemText);&&&&&&&&&&&&&&&&&& case 1: //填充子项1&&&&&&&&&&& lstrcpy(pItem-&pszText,m_Items[iItemIndx].m_strSubItem1Text);&&&&&&&&&&&&&&&&&& case 2: //填充子项2&&&&&&&&&&& lstrcpy(pItem-&pszText,m_Items[iItemIndx].m_strSubItem2Text);&&&&&&&&&&&&&& }}/*注意,多数情况下要使用lstrcpyn ,因为最多字符的个数由pItem-&cchTextMax给出:&&&&&&& lstrcpyn(pItem-&pszText, text, pItem-&cchTextMax);*/
if (pItem-&mask & LVIF_IMAGE) //是否请求图像&&&&&&& pItem-&iImage= m_Items[iItemIndx].m_iImageI
甚至连某行数据是否选中(当有checkbox的情况下)的信息也需要由用户自己来维护,例如://是否显示该行的选择信息?if(IsCheckBoxesVisible()) //自定义函数{&&& pItem-&mask |= LVIF_STATE;&&& pItem-&stateMask = LVIS_STATEIMAGEMASK;
&&& if(m_database[itemid].m_checked)&&& {&&&&&&&& pItem-&state = INDEXTOSTATEIMAGEMASK(2);&&& }&&& else&&& {&&&&&&&& pItem-&state = INDEXTOSTATEIMAGEMASK(1);&&&& }}
2、处理 LVN_ODFINDITEM 消息
在资源管理器里面,定位到某个文件夹,会显示很多文件,如果按下键盘的&A&,则资源管理器会自动找到名字以 'A'打头的文件夹或者文件, 并选择该文件。继续按 A,如果还有其它名字以'A'打头的文件,则下一个文件被选中。如果输入 "AB",则 'AB'打头的文件被选中。这就是列表控件的自动查找功能。
当虚拟列表收到一个LVM_FINDITEM消息,它也会发送这个消息通知父窗口查找目标元素。要搜索的信息通过 LVFINDINFO 结构给出。它是 NMLVFINDITEM 结构的一个成员。当找到要搜索的数据后,应该把该数据的索引(行号)返回,如果没有找到,则返回-1。
以对话框为例,响应函数大致如下:
//================= 例子代码=====================================void CVirtualListDlg::OnOdfinditemList(NMHDR* pNMHDR, LRESULT* pResult)&{&&& // pNMHDR 里面是要查找的元素的信息&&& // 要选中的目标元素的行号最后要保存在 pResult 中, 这是关键!
&&& NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)pNMHDR;
&&& /* pFindInfo-&iStart 是查找的起始位置,一直到最后,然后从头开始,如果没有找到合适的,最终停留在iStart*/
&&& *pResult = -1;
&&& //是否按照文字查找?&&& if( (pFindInfo-&lvfi.flags & LVFI_STRING) == 0 )&&& {&&&&&&&&&& }
&&& //这是我们要找的字符串&&& CString searchstr = pFindInfo-&lvfi.
&&& int startPos = pFindInfo-&iS//保存起始位置
&&& //判断是否最后一行&&& if(startPos &= m_list.GetItemCount())&&&&&&& startPos = 0;
&&& int currentPos=startP&&&&&&& //开始查找&&& do&&& {&&&&&&&&&&&&&&& if( _tcsnicmp(m_database[currentPos].m_name,&&&&&&&&&&&&&&&&& searchstr, searchstr.GetLength()) == 0)&&&&&&& {&&&&&&&&&&& //选中这个元素,停止查找&&&&&&&&&&& *pResult = currentP&&&&&&&&&&&&&&&&&& }
&&&&&&& currentPos++;
&&&&&&& //从头开始&&&&&&& if(currentPos &= m_list.GetItemCount())&&&&&&&&&&& currentPos = 0;
&&& }while(currentPos != startPos);&&&&&&&&}
显然,如果数据很多,必须实现一个快速查找的方法。
关于pFindInfo-&lvfi里面的信息的详细说明可以参考 MSDN。
3、处理 LVN_ODCACHEHINT 消息。
假如我们从数据库或者其它地方读取数据的速度比较慢,则可以利用这个消息,批量读取一些数据,然后根据请求,逐个提供给虚拟列表。LVN_ODCACHEHINT消息的用途就是给程序一个缓冲数据的机会。以提高程序的性能。
//================= 例子代码=====================================使用 ClassWizard 重载 OnChildNotify 函数,检查是否 LVN_ODCACHEHINT 消息,然后准备缓冲数据:
NMLVCACHEHINT* pcachehint=NULL;
NMHDR* phdr = (NMHDR*)lP
if(phdr-&code == LVN_ODCACHEHINT){&&&& pcachehint= (NMLVCACHEHINT*)&&&& //自定义函数,准备指定范围的数据到缓冲区&&&& PrepCache(pcachehint-&iFrom, pcachehint-&iTo);}else ...
注意,如果消息不是 LVN_ODCACHEHINT,则要传递给基类进行处理。
五、如何修改ListCtrl显示的数据。
由于是程序自己维护数据,所以只需修改数据库中的数据,然后调用CListCtrl::RedrawItems函数进行重画即可。
六、数据的选择状态和选择框
CListCtrl可以显示checkbox选择框。有些情况下是很有用的。对于正常的listctrl,用户可以用鼠标来修改某个元素的选择状态,但是对于虚拟列表就不行了。必须自己处理一些消息,然后自己保存数据的选中状态:
void CVirtualListDlg::ToggleCheckBox(int item){&&& m_database[item].m_checked = !m_database[item].m_&&& m_list.RedrawItems(item, item);}
处理 LVN_KEYDOWN消息,添加对空格键 的响应,用于切换选择状态:
void CVirtualListDlg::OnKeydownList(NMHDR* pNMHDR, LRESULT* pResult)&{&&& LV_KEYDOWN* pLVKeyDown = (LV_KEYDOWN*)pNMHDR;
&&& if( pLVKeyDown-&wVKey == VK_SPACE )&&& {&&&&&& int item = m_list.GetSelectionMark();&&&&&&& if(item != -1)&&&&&&&&&&& ToggleCheckBox(item);&&& }
&&& *pResult = 0;}
然后处理 NM_CLICK 消息:
void CVirtualListDlg::OnClickList(NMHDR* pNMHDR, LRESULT* pResult)&{&&& NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
&&& LVHITTESTINFO&&& hitinfo.pt = pNMListView-&ptA
&&& int item = m_list.HitTest(&hitinfo);
&&& if(item != -1)&&& {&&&&&&& //看看鼠标是否单击在 check box上面了?&&&&&&& if( (hitinfo.flags & LVHT_ONITEMSTATEICON) != 0)&&&&&&& {&&&&&&&&&&& ToggleCheckBox(item);&&&&&&& }&&& }&&&&&&& *pResult = 0;}
七、备注:
&&& 1、虚拟列表无法进行排序。
&&& 2、虚表的一个优点是容易保持和数据库的同步。修改数据库中的数据,然后重画list十分容易而且高效。
&&& 3、虚表的另一个优点是可以根据需要产生数据。比如在某一列加上行号。
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
虚拟列表控件加载大数据行
平常所用到的列ListView/ListCtrl控件,都是只有行至几百行数据,直至今日,在项目中遇到了上10W量级数据条,终于感觉到普通加载的艰辛,遂到网上乱找一通,发现大同小异,转载了这篇比较详细的,后面代码所用到的m_Items,为存放的列表的数据结构列表, 这篇文章虽详尽,改日做一个DEMO,
一.什么是 ...
[VC/MFC]虚拟列表控件 一.什么是虚拟列表控件 虚拟列表控件是指带有LVS_OWNERDATA风格的列表控件..二.为什么使用虚拟列表控件我们知道,通常使用列表控件CListCtrl,需要调用InsertItem把要显示的数据插入列表中,之后我们就不必关心数据在哪里了,这是因为控件自己开辟了内存空间来保存这些数据.现在假设我们要显示一个数据库,里面的信 ...
/zh-cn/library/cc468308(v=vs.71).aspx 虚拟列表控件 Visual Studio .NET 2003 4(共 4)对本文的评价是有帮助 - 评价此主题 虚拟列表控件指具有 LVS_OWNERDATA 样式的列表视图 (ListView) 控件.该样式启用控件来支持项数达到
本文主要讲述使用VS2012 MFC的CListCtrl(列表)控件加载类似于QQ界面的图片与文字数据.主要通过CListCtrl::InsertColumn.InsertItem.SetItemText向列表插入数据,CImageList插入BMP图片或ICON图标. 一.创建项目及界面 1.创建项目
创建项目名为&QQList&quot ...
CListCtrl 类封装&列表视图控件&功能,显示每个包含图标(列表视图中)和标签的收集.除图标和标签外,每一项还能有显示在图标和标签的右边的列中的信息.此控件(以及CListCtrl类)只适用于运行于Windows 95和Windows NT 3.51及更高版本的程序. 视图 列表视图控件可用四种不同方式显示其内容,称为&视 ...
在使用CListCtrl控件Report显示风格时,需要设置列标题信息,否则不能向控件中添加数据信息,编辑列标题需要 使用InsertColumn方法:
m_ListCtrl.InsertColumn(0, &姓名&, LVCFMT_LEFT, 150, 0);
m_ListCtrl.InsertColumn(1, &quot ...
在网上搜索了下,结果不怎么理想,很多类似的答案: POSITION pos = pList-& GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0( &No items were selected!\n &); else { while (pos) { int nItem
推荐网站:http://www.vckbase.net/(VC知识库) 一.列表控件(CListCtrl) 了解一个单词先:Item行,一般我们都是用到位报表形式,即report,可以在列表控件的属性里设置.这里也只介绍这种形式.(一般都是会设置一个列表控件的变量) 1.其中InsertItem用于向列表控件插入一行,并设置第零列的值,如果有多列,该行其他列 ...& VS2010/MFC编程入门之二十九(常用控件:列表视图控件List Control 下)
VS2010/MFC编程入门之二十九(常用控件:列表视图控件List Control 下)
&&&&&& 上一节是关于,简单介绍了列表视图控件,其通知消息的处理和有关结构体的定义。本节继续讲解下半部分,包括列表视图控件的创建、CListCtrl类的主要成员函数和CListCtrl类应用实例。&&&&&& 列表视图控件的创建&&&&&&&同样为列表视图控件的操作提供了CListCtrl类。&&&&&& 如果我们不想在对话框模板中直接拖入List Control来使用列表视图控件,而是希望动态创建它,则要用到CListCtrl类的成员函数Create函数,原型如下:virtual BOOL Create(&& DWORD dwStyle,&& const RECT& rect,&& CWnd* pParentWnd,&& UINT nID );&&&&&& 参数rect为列表视图控件的位置和尺寸,pParentWnd为指向父窗口的指针,nID指定列表视图控件的ID,最复杂的一个参数同样还是dwStyle,它用于设定列表视图控件的风格,可以是以下风格的组合:&&&&&&&&&&&&&& 风格&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 含义&&&&&&&LVS_ALIGNLEFT&&&&&&&&&&&&&&&&&&&&&&& 显示格式是大图标或小图标时,标签放在图标的左边&&&&&& LVS_ALIGNTOP&&&&&&&&&&&&&&&&&&&&&&&& 显示格式是大图标或小图标时,标题放在图标的上边&&&&&& LVS_AUTOARRANGE&&&&&&&&&&&&&&&& 显示格式是大图标或小图标时,自动排列控件中的列表项&&&&&& LVS_EDITLABELS&&&&&&&&&&&&&&&&&&&&& 用户可以修改标签文本&&&&&& LVS_ICON&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &指定大图标显示格式&&&&&& LVS_LIST&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 指定列表显示格式&&&&&& LVS_NOCOLUMNHEADER&&&&&&&&&在报表格式中不显示列的表头&&&&&& LVS_NOLABELWRAP&&&&&&&&&&&&&&&&显示格式是大图标时,使标签文本单行显示。默认是多行显示&&&&&& LVS_NOSCROLL&&&&&&&&&&&&&&&&&&&&&& 列表视图控件无滚动条,此风格不能与LVS_LIST或LVS_REPORT组合使用&&&&&& LVS_NOSORTHEADER&&&&&&&&&&&& &报表格式的列表视图控件的表头不能作为排序按钮使用&&&&&& LVS_OWNERDRAWFIXED&&&&&&&&由控件的拥有者负责绘制表项&&&&&& LVS_REPORT&&&&&&&&&&&&&&&&&&&&&&&&&& 指定报表显示格式&&&&&& LVS_SHAREIMAGELISTS&&&&&&&&&& 使列表视图共享图像序列&&&&&& LVS_SHOWSELALWAYS&&&&&&&&&&&即使控件失去输入焦点,仍显示出项的选择状态&&&&&& LVS_SINGLESEL&&&&&&&&&&&&&&&&&&&&&& 指定只能有一个列表项被选中。默认时可以多项选择&&&&&& LVS_SMALLICON&&&&&&&&&&&&&&&&&&&&& 指定小图标显示格式&&&&&& LVS_SORTASCENDING&&&&&&&&&&&& 按升序排列列表项&&&&&& LVS_SORTDESCENDING&&&&&&&&&&按降序排列列表项&&&&&&&与前面的控件一样,除了以上风格一般我们还要为列表视图控件设置WS_CHILD和WS_VISIBLE风格。对于直接在对话框模板中创建的列表视图控件,其属性页中的属性与上述风格是对应的,例如,属性Alignment默认为Left,也就等价于指定了LVS_ALIGNLEFT风格。&&&&&& CListCtrl类的主要成员函数&&&&&& CListCtrl类有很多成员函数,鸡啄米这里就为大家介绍几个常用的主要成员函数。&&&&&&&UINT GetSelectedCount( )&&&&&& 该函数返回列表视图控件中被选择列表项的数量。&&&&&& POSITION GetFirstSelectedItemPosition( )&&&&&& 获取列表视图控件中第一个被选择项的位置。返回的POSITION值可以用来迭代来获取其他选择项,可以当作参数传入下面的GetNextSelectedItem函数来获得选择项的索引。如果没有被选择项则返回NULL。&&&&&& int GetNextSelectedItem(POSITION& pos)&&&&&& 该函数获取由pos指定的列表项的索引,然后将pos设置为下一个位置的POSITION值。参数pos为之前调用GetNextSelectedItem或GetFirstSelectedItemPosition得到的POSITION值的引用。返回值就是pos指定列表项的索引。&&&&&& int GetItemCount( )&&&&&& 获取列表视图控件中列表项的数量。&&&&&& int InsertColumn(int nCol,const LVCOLUMN* pColumn );&&&&&& int InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,int nWidth = -1,int nSubItem = -1 );&&&&&& 这两个函数用于在报表式列表视图控件中插入列。第一个函数中,nCol参数为插入列的索引,pColumn参数指向LVCOLUMN结构,其中包含了插入列的属性。第二个函数中,nCol参数也是插入列的索引,lpszColumnHeading参数为列标题字符串,nFormat参数为列中文本的对齐方式,可以是LVCFMT_LEFT、LVCFMT_RIGHT或LVCFMT_CENTER,nWidth参数为列宽,nSubItem为插入列对应列表子项的索引。两个函数在成功时都返回新列的索引,失败都返回-1。&&&&&& BOOL DeleteColumn(int nCol);&&&&&& 该函数用于删除列表视图控件中的某列。参数nCol为删除列的索引。删除成功则返回TRUE,失败返回FALSE。&&&&&& int InsertItem(int nItem,LPCTSTR lpszItem);&&&&&& 向列表视图控件中插入新的列表项。参数nItem为要插入项的索引,参数lpszItem为要插入项的标签字符串。如果插入成功则返回新列表项的索引,否则返回-1。&&&&&& BOOL DeleteItem(int nItem);&&&&&& 从列表视图控件中删除某个列表项。参数nItem指定了要删除的列表项的索引。删除成功则返回TRUE,否则返回FALSE。&&&&&& CString GetItemText(int nItem,int nSubItem)&&&&&& 获取指定列表项或列表子项的显示文本。参数nItem指定了列表项的索引,参数nSubItem指定了列表子项的索引。&&&&&&& BOOL SetItemText(int nItem,int nSubItem,LPCTSTR lpszText);&&&&&& 设置指定列表项或列表子项的显示文本。参数nItem和nSubItem同GetItemText。参数lpszText为要设置的显示文本字符串。如果设置成功则返回TRUE,否则返回FALSE。&&&&&& DWORD_PTR GetItemData(int nItem)&&&&&&&该函数用于获取指定列表项的附加32位数据。参数nItem为列表项的索引。返回值就是由nItem指定列表项的附加32位数据。&&&&&& BOOL SetItemData(int nItem,DWORD_PTR dwData);&&&&&& 该函数用于为指定列表项设置附加32位是数据。参数nItem为列表项的索引,参数dwData为列表项的附加32位数据。&&&&&& CListCtrl类应用实例&&&&&& 最后鸡啄米还是给大家写一个简单的实例,说明CListCtrl类的几个成员函数及通知消息等的使用方法。因为在开发中最常用的要属报表风格的List Control了,所以鸡啄米给大家写的是一个报表List Control的例子。&&&&&& 此实例实现的功能:在单选列表视图控件中显示一个简单的编程语言排行榜,然后在用鼠标左键选择某列表项时,将选中列表项的文本显示到编辑框中。下面是具体实现步骤:&&&&&& 1. 创建一个基于对话框的MFC工程,名称设置为&Example29&。&&&&&& 2. 在自动生成的对话框模板IDD_EXAMPLE29_DIALOG中,删除&TODO: Place dialog controls here.&静态文本控件、&OK&按钮和&Cancel&按钮。添加一个List Control控件,ID设置为IDC_PROGRAM_LANG_LIST,View属性设为Report,即为报表风格,Single Selection属性设为True。再添加一个静态文本控件和一个编辑框,静态文本控件的Caption属性设为&选择的语言:&,编辑框的ID设为IDC_LANG_SEL_EDIT,Read Only属性设为True。此时的对话框模板如下图:&&&&&& 3. 为列表视图控件IDC_PROGRAM_LANG_LISTm_programLangList。&&&&&& 4. 在对话框初始化时,我们将编程语言排行榜加入到列表视图控件中,那么需要修改CExample29Dlg::OnInitDialog()函数为:
BOOL&CExample29Dlg::OnInitDialog() &&
&&&&CDialogEx::OnInitDialog(); &&
&&&&ASSERT((IDM_ABOUTBOX&&&0xFFF0)&==&IDM_ABOUTBOX); &&
&&&&ASSERT(IDM_ABOUTBOX&&&0xF000); &&
&&&&CMenu*&pSysMenu&=&GetSystemMenu(FALSE); &&
&&&&if&(pSysMenu&!=&NULL) &&
&&&&&&&&BOOL&bNameV &&
&&&&&&&&CString&strAboutM &&
&&&&&&&&bNameValid&=&strAboutMenu.LoadString(IDS_ABOUTBOX); &&
&&&&&&&&ASSERT(bNameValid); &&
&&&&&&&&if&(!strAboutMenu.IsEmpty()) &&
&&&&&&&&{ &&
&&&&&&&&&&&&pSysMenu-&AppendMenu(MF_SEPARATOR); &&
&&&&&&&&&&&&pSysMenu-&AppendMenu(MF_STRING,&IDM_ABOUTBOX,&strAboutMenu); &&
&&&&&&&&} &&
&&&&SetIcon(m_hIcon,&TRUE);&&&&&&&&&&&
&&&&SetIcon(m_hIcon,&FALSE);&&&&&&&&&&
&&&&CRect& &&
&&&&m_programLangList.GetClientRect(&rect); &&
&&&&m_programLangList.SetExtendedStyle(m_programLangList.GetExtendedStyle()&|&LVS_EX_FULLROWSELECT&|&LVS_EX_GRIDLINES); &&
&&&&m_programLangList.InsertColumn(0,&_T(&语言&),&LVCFMT_CENTER,&rect.Width()/3,&0); &&
&&&&m_programLangList.InsertColumn(1,&_T(&2012.02排名&),&LVCFMT_CENTER,&rect.Width()/3,&1); &&
&&&&m_programLangList.InsertColumn(2,&_T(&2011.02排名&),&LVCFMT_CENTER,&rect.Width()/3,&2); &&
&&&&m_programLangList.InsertItem(0,&_T(&Java&)); &&
&&&&m_programLangList.SetItemText(0,&1,&_T(&1&)); &&
&&&&m_programLangList.SetItemText(0,&2,&_T(&1&)); &&
&&&&m_programLangList.InsertItem(1,&_T(&C&)); &&
&&&&m_programLangList.SetItemText(1,&1,&_T(&2&)); &&
&&&&m_programLangList.SetItemText(1,&2,&_T(&2&)); &&
&&&&m_programLangList.InsertItem(2,&_T(&C#&)); &&
&&&&m_programLangList.SetItemText(2,&1,&_T(&3&)); &&
&&&&m_programLangList.SetItemText(2,&2,&_T(&6&)); &&
&&&&m_programLangList.InsertItem(3,&_T(&C++&)); &&
&&&&m_programLangList.SetItemText(3,&1,&_T(&4&)); &&
&&&&m_programLangList.SetItemText(3,&2,&_T(&3&)); &&
&&&&return&TRUE;&&&&
}&&&&&&&& 5. 我们希望在选中列表项改变时,将最新的选择项实时显示到编辑框中,那么可以使用NM_CLICK通知消息。为列表框IDC_PROGRAM_LANG_LIST的通知消息NM_CLICKCExample29Dlg::OnNMClickProgramLangList,并修改如下:
void&CExample29Dlg::OnNMClickProgramLangList(NMHDR&*pNMHDR,&LRESULT&*pResult) &&
&&&&LPNMITEMACTIVATE&pNMItemActivate&=&reinterpret_cast&LPNMITEMACTIVATE&(pNMHDR); &&
&&&&*pResult&=&0; &&
&&&&CString&strLangN&&&&&&
&&&&NMLISTVIEW&*pNMListView&=&(NMLISTVIEW*)pNMHDR; &&
&&&&if&(-1&!=&pNMListView-&iItem)&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&strLangName&=&m_programLangList.GetItemText(pNMListView-&iItem,&0); &&
&&&&&&&&&&
&&&&&&&&SetDlgItemText(IDC_LANG_SEL_EDIT,&strLangName); &&
}&&&&&&&& 6. 运行程序,弹出结果对话框,在对话框的列表框中用鼠标改变选中项时,编辑框中的显示会相应改变。效果图如下:&&&&&&&关于列表视图控件List Control的内容总算讲完了,内容不少,但实际上这些还只是一部分,在实际开发中会遇到各种问题,需要大家去查阅MSDN或上网找资料等来解决。最后鸡啄米仍然感谢大家对本VS2010/MFC教程的关注。
除非特别注明,文章均为原创
转载请标明本文地址:
作者:鸡啄米
&&( 21:47:5)&&( 22:36:38)&&( 21:53:33)&&( 0:49:15)&&( 23:21:17)&&( 21:47:59)&&( 0:24:18)&&( 0:15:31)&&( 22:29:38)&&( 21:26:10)
编程是博主的强项
真心感谢博主这么无私的分享和奉献啊,最近要用MFC做界面,看了好多资料效果都不是非常明显,后来朋友给我发这个链接,很快就搞定了。必须的留个言谢谢博主,偶会继续支持你的!谢谢!鸡啄米 于
23:13:07 回复谢谢支持,也谢谢你那位朋友
纯粹路过,支持下~
了解了,进来支持一下
呵呵,写的很专业鸡啄米 于
22:25:31 回复谢谢,常来常往啊
大有帮助,期待你的后续作品!!鸡啄米 于
20:05:15 回复也希望你能常来,谢谢
楼主讲的很有条理 让我一看就懂 而且很喜欢看 哈哈。。。看着好舒心啊
可以说是网上最实用的mfc文档,谢谢楼主。鸡啄米 于
22:58:09 回复谢谢评价如此之高
一步一步跟着楼主学习,顶一个
感谢楼主的分享,交流精神,看来很多篇,特此赞一个!
感谢博主,觉得博主思路很清晰,我是真正从您写的内容里获得了帮助。直接看MSDN太多太乱,先看博主的文章有了个大概思路,细节问题再看MSDN就很高效了。谢谢博主。鸡啄米 于
11:22:20 回复直接看msdn的话确实有些难以入手,msdn适合做查询之用。
楼主,如何要插入的为一个表达式的计算结果,比如m_programLangList.SetItemText(0, 1, _T(&1&))中_T(&&)想输入数组a[5]的值,该怎么呢?
谢谢楼主!
介绍的内容有点少,再多点,并且举的例子尽量覆盖日常开发中常用的功能就可以出书了,例如CListCtrl经常需要点击表头排序,就可以在例子中实现。
请问下博主 如果我想选中一行后 在编辑框中 显示一行的数据 应该怎么弄?
楼主太棒了,写出这么好的东西,让我的学习之路有了方向,太喜欢您写的东西了。非常感谢您的分享,我有个小问题想麻烦您帮我解答一下~// 为列表视图控件添加三列
m_programLangList.InsertColumn(0, _T(&语言&), LVCFMT_CENTER, rect.Width()/3, 0);
m_programLangList.InsertColumn(1, _T(&2012.02排名&), LVCFMT_CENTER, rect.Width()/3, 1);
m_programLangList.InsertColumn(2, _T(&2011.02排名&), LVCFMT_CENTER, rect.Width()/3, 2);
为什么最后一个参数分别是0,1,2
这个是列表子项的索引?
不太明白啊
楼主太棒了,写出这么好的东西,让我的学习之路有了方向,太喜欢您写的东西了。非常感谢您的分享,我有个小问题想麻烦您帮我解答一下~// 为列表视图控件添加三列
m_programLangList.InsertColumn(0, _T(&语言&), LVCFMT_CENTER, rect.Width()/3, 0);
m_programLangList.InsertColumn(1, _T(&2012.02排名&), LVCFMT_CENTER, rect.Width()/3, 1);
m_programLangList.InsertColumn(2, _T(&2011.02排名&), LVCFMT_CENTER, rect.Width()/3, 2);
为什么最后一个参数分别是0,1,2
这个是列表子项的索引?
不太明白啊
楼主,有没有关于MFC 连接数据库的知识点讲解啊,比如说ado模式连接,
楼主,能否教一下排序,拜托了
跟着一篇一篇学的 每一篇都做了笔记 到这里已经11页~
跟着楼主的脚步走准没错的!永远支持楼主~~~~~~~~~
鸡啄米大哥您好,首先很感谢您一直更新着博客,我每天都看您的文章感觉收获颇丰。刚刚在演练实例的时候,由于没注意到在最后一步添加消息处理函数时,直接双击了列表视图控件,跳出的是 OnLvnItemchangedProgramLangList(NMHDR *pNMHDR, LRESULT *pResult);函数,而非OnNMClickProgramLangList函数,于是我把原来的删除重新添加NMClickProgramLangList函数,但在运行时出现链接错误error LNK2001: 无法解析的外部符号 &public: void __thiscall CExample29Dlg::OnLvnItemchangedProgramLangList(struct tagNMHDR *,long *)& (?OnLvnItemchangedProgramLangList@CExample29Dlg@@QAEXPAUtagNMHDR@@PAJ@Z)1&D:\VS\cxu\mfc\Example29\Debug\Example29.exe : fatal error LNK1120: 1 个无法解析的外部命令1&,不知道如何修改?wegen 于
10:04:59 回复不知道你现在看不看得到,我之前也出现这样的情况,原因是你添加了OnLvnItemchangedProgramLangList(NMHDR *pNMHDR, LRESULT *pResult);函数后会在.h文件里声明了这个函数,而你可能后来只是在.cpp文件里把它删了,但是声明还在,所以要在.h文件里把函数声明也删了。
对我们这些新手来说,博主写的知识点显浅易懂 还有分支知识点导航 太方便了 非常感谢
勉强会C++基础的程序媛小菜鸟一只,打算按图索骥弄界面,楼主的教程很好很全面,谢谢楼主花心思写了这么好的MFC教程!
感谢博主,最近刚开始学MFC,这个教程刚好用来熟悉各个控件和MFC的风格,受益颇深。
你好,我安全按着教程做的 但是出现了一个问题,debug assertion failed
痛苦作为一个小白死活找不到OnInitDialog啊,,,求救秋风 于
15:07:05 回复在新建项目的向导中应用程序类型选择(基于对话框),在生成的类中选择带有(xxxDlg)的类型其中xxx为你项目的名称。这样你就找到OnInitDialog了。如果不是主界面,是在资源视图中添加资源得到的Dialog那么这个函数是要自己创建并添加到类声明中的。
请问一下,如果要输出到列表的东西是不确定的,那应该怎么输出,m_programLangList.InsertItem(0, _T(&Java&));
比如这个Java是储存在一个CString或者string的类型里,应该怎样弄呀
不是m_programLangList.InsertColumn(0, _T(&语言&) , LVCFMT_CENTER , rect.Width()/3, 0);中设置了索引为0列是为居中对齐,怎么结果是左对齐?
完全随机文章

我要回帖

更多关于 clistctrl动态创建 的文章

 

随机推荐