Clistctl控件如何显示固定的数目列表项(item)

lichen2889 2016-10-17 08:59:07
在做一个将接收到的数据显示出来的界面(外部数据大概1ms就发送一次),因为数据信息是一个结构体,所以需要使用到多列的CListctl控件。现在想实现的功能是只显示3000条数据,小于3000条时用InsertItem()插入新的一行列表项,用SetItemText()写入每列的信息,大于3000条时,新接收到的数据显示在第3000行,剩下的数据全部上移。类似于一个一定长度的队列,新的数据push_back,头数据pop_front。
我现在的做法是有新的数据接收到时,先从第二行开始,将每行数据取出GetItemText(),然后再用SetItemText()复制到上一行,总共要执行2999次,最后再将新接收到的数据通过SetItemText()写到第3000行。
这么做有很大的问题,因为我的数据是1ms就接收到一条,现在感觉GetItemText()再SetItemText()到上一行,循环2999次会占用很多时间,导致新数据刷新到界面很慢。
请高手指导指导,有没有更好的方法?只显示固定3000行数据,每次新来的数据显示在最后一行,其余数据上移,第一条数据可以丢失,谢谢大家!
...全文
467 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
lichen2889 2016-10-20
  • 打赏
  • 举报
回复
谢谢各位大神,现在就是显示序号的问题了,如何让序号与行数相关联,或者说显示到固定行数以后第一列的序号就不变了,从0到这一行的序号,再次感谢大家!
lichen2889 2016-10-19
  • 打赏
  • 举报
回复
引用 13 楼 向立天的回复:
[quote=引用 12 楼 lichen2889 的回复:] [quote=引用 10 楼 redfly001的回复:]个人总结认为,大致上有3种方式: 1. 不以精确的3000行方法(这个说法好蹩脚,自己想的)。如楼上所说,可以在最下面插入一条数据,然后看是否超过了3000条,如果超过了就删除第一条数据。由于你接收数据的频率很高,所以此方法估计闪烁的比较厉害 2. 虚列表,基本方法楼上已说。这里你需要对它进行优化。你不断地在下面插入新的数据,直到3000条时为止。满3000条后,需要两件事: A. 更新内存 B. 刷新当前能看见的条目。这个刷新应该不能使用Invalidate()函数,因为它会出现闪烁。(后面是我的理解,没有实际操作过,所以可能不对)这里可能需要发送个设置文本的消息来使各条目重新获取文本并更新,具体上你可以查看一下是否有相关的虚函数或者消息可用,不过要注意在虚列表的模式下对应的策略是否有效。 内存列表未必要使用push、pop这种方式,可以循环利用,这样只更新内存的内容,就不需要不断地分配和删除,效率应该会高,速度上会比较有利,但是对索引的标记需要增加策略来管理它。 3. 自己实现DRAWITEM。个人觉得这个是比较麻烦的,虽然感觉简单。
十分感谢这位大神,我试了你说的第一个方法,没有用虚列表,用deleteitem()删除第一行再插入最后一行,效果是最好的,就算发送频率很快界面也没有出现闪烁,但是现在的问题是我第一列的序号也会删除,比如我现在接收了3006条数据,第一列的序号就会从7开始,最后我插入时写入的序号都是3000,也就会在最后出现6个3000的序号,这是不想看到的结果,如果我在插入新数据后循环3000次修改第一列的序号又会占用很多时间。 所以请问大神,有没有类似于deleteitem()的函数,只删除从第二列开始的数据,而第一列的序号保持不变?谢谢啦~[/quote] 你可以只把序号更新一下,3000个序号应该不会太费事[/quote] 3000这个数只是一个泛指,留给用户自己选的,用户可以选1到千万级以内的数目,如果最大是三千我用setitemtext()循环设置一下序号就好,问题如果数目多了循环比较耗时
向立天 2016-10-19
  • 打赏
  • 举报
回复
引用 12 楼 lichen2889 的回复:
[quote=引用 10 楼 redfly001的回复:]个人总结认为,大致上有3种方式: 1. 不以精确的3000行方法(这个说法好蹩脚,自己想的)。如楼上所说,可以在最下面插入一条数据,然后看是否超过了3000条,如果超过了就删除第一条数据。由于你接收数据的频率很高,所以此方法估计闪烁的比较厉害 2. 虚列表,基本方法楼上已说。这里你需要对它进行优化。你不断地在下面插入新的数据,直到3000条时为止。满3000条后,需要两件事: A. 更新内存 B. 刷新当前能看见的条目。这个刷新应该不能使用Invalidate()函数,因为它会出现闪烁。(后面是我的理解,没有实际操作过,所以可能不对)这里可能需要发送个设置文本的消息来使各条目重新获取文本并更新,具体上你可以查看一下是否有相关的虚函数或者消息可用,不过要注意在虚列表的模式下对应的策略是否有效。 内存列表未必要使用push、pop这种方式,可以循环利用,这样只更新内存的内容,就不需要不断地分配和删除,效率应该会高,速度上会比较有利,但是对索引的标记需要增加策略来管理它。 3. 自己实现DRAWITEM。个人觉得这个是比较麻烦的,虽然感觉简单。
十分感谢这位大神,我试了你说的第一个方法,没有用虚列表,用deleteitem()删除第一行再插入最后一行,效果是最好的,就算发送频率很快界面也没有出现闪烁,但是现在的问题是我第一列的序号也会删除,比如我现在接收了3006条数据,第一列的序号就会从7开始,最后我插入时写入的序号都是3000,也就会在最后出现6个3000的序号,这是不想看到的结果,如果我在插入新数据后循环3000次修改第一列的序号又会占用很多时间。 所以请问大神,有没有类似于deleteitem()的函数,只删除从第二列开始的数据,而第一列的序号保持不变?谢谢啦~[/quote] 你可以只把序号更新一下,3000个序号应该不会太费事
gz_qmc 2016-10-19
  • 打赏
  • 举报
回复
本人比较笨,没有前面那么多大师的水平 只能给楼主一个小小的建议 一般电脑屏幕1920*1080分辨率 一行字按很小的12高,不留行间距 满屏幕显示也无非是1080/12=90行 也就是你实际显示,在牛B你也只看得见100行左右,也就是100左右条记录 显示100条记录 一个循环链表,3000个节点 Head,表头 Tail,表尾 First,拿来显示的首位置 Last,拿来显示的尾位置
lichen2889 2016-10-19
  • 打赏
  • 举报
回复
引用 10 楼 redfly001的回复:
个人总结认为,大致上有3种方式: 1. 不以精确的3000行方法(这个说法好蹩脚,自己想的)。如楼上所说,可以在最下面插入一条数据,然后看是否超过了3000条,如果超过了就删除第一条数据。由于你接收数据的频率很高,所以此方法估计闪烁的比较厉害 2. 虚列表,基本方法楼上已说。这里你需要对它进行优化。你不断地在下面插入新的数据,直到3000条时为止。满3000条后,需要两件事: A. 更新内存 B. 刷新当前能看见的条目。这个刷新应该不能使用Invalidate()函数,因为它会出现闪烁。(后面是我的理解,没有实际操作过,所以可能不对)这里可能需要发送个设置文本的消息来使各条目重新获取文本并更新,具体上你可以查看一下是否有相关的虚函数或者消息可用,不过要注意在虚列表的模式下对应的策略是否有效。 内存列表未必要使用push、pop这种方式,可以循环利用,这样只更新内存的内容,就不需要不断地分配和删除,效率应该会高,速度上会比较有利,但是对索引的标记需要增加策略来管理它。 3. 自己实现DRAWITEM。个人觉得这个是比较麻烦的,虽然感觉简单。
十分感谢这位大神,我试了你说的第一个方法,没有用虚列表,用deleteitem()删除第一行再插入最后一行,效果是最好的,就算发送频率很快界面也没有出现闪烁,但是现在的问题是我第一列的序号也会删除,比如我现在接收了3006条数据,第一列的序号就会从7开始,最后我插入时写入的序号都是3000,也就会在最后出现6个3000的序号,这是不想看到的结果,如果我在插入新数据后循环3000次修改第一列的序号又会占用很多时间。 所以请问大神,有没有类似于deleteitem()的函数,只删除从第二列开始的数据,而第一列的序号保持不变?谢谢啦~
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
有时候,克服界面闪烁,需要使用Spy++跟踪消息。
schlafenhamster 2016-10-19
  • 打赏
  • 举报
回复
在 OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) 中修改
lichen2889 2016-10-19
  • 打赏
  • 举报
回复
引用 17 楼 向立天的回复:
[quote=引用 15 楼 lichen2889 的回复:] [quote=引用 6 楼 xiaohuh421的回复:]你就不能删除第一行, 然后在最后添加一行吗?
昨天看错了,还以为你让别删除第一行呢,今天按照这个方法来做,效果很好!谢谢啦,但是现在的问题是,我第一列是这条数据的序号,第一行数据删除后,序号就不能从1开始了,经过测试循环用setitemtext()写入序号又很耗时,请问还有其他的方法吗?[/quote]要不然你就弄两个listctrl吧,一个只显示序号,一个现实内容,这样序号这列可以不用动 然后对齐的时候,序号这列增加删除的都是最后一行就是了[/quote] 嗯,今天下午就这么试过,但是两个列表数据一多必然会有两个滚动条,一来界面难看(有办法隐藏滚动条吗),二来如果要查看数据还要将两个滚动条消息关联?不能滑动数据这边的滚动条,序号那边的不动吧,所以新的问题又产生了……唉,最近搞这个好头疼
lichen2889 2016-10-19
  • 打赏
  • 举报
回复
引用 16 楼 schlafenhamster的回复:
“第一列的序号” 必须与 item 的 ID 相关。
是的,相关起来就好办多了,比如删除第一行第二行的iItem自然就变成0了,问题是怎么关联呢?大神有没有好办法?
向立天 2016-10-19
  • 打赏
  • 举报
回复
引用 15 楼 lichen2889 的回复:
[quote=引用 6 楼 xiaohuh421的回复:]你就不能删除第一行, 然后在最后添加一行吗?
昨天看错了,还以为你让别删除第一行呢,今天按照这个方法来做,效果很好!谢谢啦,但是现在的问题是,我第一列是这条数据的序号,第一行数据删除后,序号就不能从1开始了,经过测试循环用setitemtext()写入序号又很耗时,请问还有其他的方法吗?[/quote]要不然你就弄两个listctrl吧,一个只显示序号,一个现实内容,这样序号这列可以不用动 然后对齐的时候,序号这列增加删除的都是最后一行就是了
schlafenhamster 2016-10-19
  • 打赏
  • 举报
回复
“第一列的序号” 必须与 item 的 ID 相关。
lichen2889 2016-10-19
  • 打赏
  • 举报
回复
引用 6 楼 xiaohuh421的回复:
你就不能删除第一行, 然后在最后添加一行吗?
昨天看错了,还以为你让别删除第一行呢,今天按照这个方法来做,效果很好!谢谢啦,但是现在的问题是,我第一列是这条数据的序号,第一行数据删除后,序号就不能从1开始了,经过测试循环用setitemtext()写入序号又很耗时,请问还有其他的方法吗?
lichen2889 2016-10-18
  • 打赏
  • 举报
回复
引用 6 楼 xiaohuh421的回复:
你就不能删除第一行, 然后在最后添加一行吗?
我需要显示的总数是3000条啊,如果不删除第一行那就有3001行了
xiaohuh421 2016-10-18
  • 打赏
  • 举报
回复
你就不能删除第一行, 然后在最后添加一行吗?
lichen2889 2016-10-18
  • 打赏
  • 举报
回复
引用 4 楼 lichen2889的回复:
各位大神,我大概了解了虚拟列表,现在正在写OnGetdispinfoList()函数,现在不知道如何将数据在此函数链接到控件中,我定义了一个队列: 其中vci_can_obj是一个结构体,frameinfo是接收到的数据,max_count=3000,我现在把接收到数据存在队列中,但不知道如何通过OnGetdispinfoList()函数显示在列表控件里,谢谢各位大神!
这是代码: deque<VCI_CAN_OBJ> info; info.push_back(frameinfo); int n=info.size(); if(n>max_count) { info.pop_front(); }
lichen2889 2016-10-18
  • 打赏
  • 举报
回复
各位大神,我大概了解了虚拟列表,现在正在写OnGetdispinfoList()函数,现在不知道如何将数据在此函数链接到控件中,我定义了一个队列: 其中vci_can_obj是一个结构体,frameinfo是接收到的数据,max_count=3000,我现在把接收到数据存在队列中,但不知道如何通过OnGetdispinfoList()函数显示在列表控件里,谢谢各位大神!
red-fly 2016-10-18
  • 打赏
  • 举报
回复
个人总结认为,大致上有3种方式: 1. 不以精确的3000行方法(这个说法好蹩脚,自己想的)。如楼上所说,可以在最下面插入一条数据,然后看是否超过了3000条,如果超过了就删除第一条数据。由于你接收数据的频率很高,所以此方法估计闪烁的比较厉害 2. 虚列表,基本方法楼上已说。这里你需要对它进行优化。你不断地在下面插入新的数据,直到3000条时为止。满3000条后,需要两件事: A. 更新内存 B. 刷新当前能看见的条目。这个刷新应该不能使用Invalidate()函数,因为它会出现闪烁。(后面是我的理解,没有实际操作过,所以可能不对)这里可能需要发送个设置文本的消息来使各条目重新获取文本并更新,具体上你可以查看一下是否有相关的虚函数或者消息可用,不过要注意在虚列表的模式下对应的策略是否有效。 内存列表未必要使用push、pop这种方式,可以循环利用,这样只更新内存的内容,就不需要不断地分配和删除,效率应该会高,速度上会比较有利,但是对索引的标记需要增加策略来管理它。 3. 自己实现DRAWITEM。个人觉得这个是比较麻烦的,虽然感觉简单。
lichen2889 2016-10-18
  • 打赏
  • 举报
回复
通过这个帖子http://blog.csdn.net/love3s/article/details/8120975?from=singlemessage&isappinstalled=1已经把功能实现的差不多了,但是界面闪烁比较厉害,而且我在我的VC里面没有找到LVS_EX_DOUBLEBUFFER风格,还是请大神帮帮忙吧!
paschen 2016-10-17
  • 打赏
  • 举报
回复
https://my.oschina.net/laopiao/blog/99320
加载更多回复(2)

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧