加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何有选择地使Owner Drawn TListBox的画布无效?

发布时间:2020-12-15 09:37:57 所属栏目:大数据 来源:网络整理
导读:我有一个所有者绘制TListBox(lbVirtualOwnerDraw),其内容得到动态更新(一秒钟内可以有多达10个更新).一次最多可以在列表框中放置300个项目.每个项目可能有大约5行文本和与之关联的图像.每当刷新一个项目时,我都必须刷新(或使其无效)TListBox,以便VCL框架调用
我有一个所有者绘制TListBox(lbVirtualOwnerDraw),其内容得到动态更新(一秒钟内可以有多达10个更新).一次最多可以在列表框中放置300个项目.每个项目可能有大约5行文本和与之关联的图像.每当刷新一个项目时,我都必须刷新(或使其无效)TListBox,以便VCL框架调用ListBoxDrawItem.但由于所有冗余重新涂漆,这会对整体性能产生不利影响.所以我的问题是:

>有没有办法只使画布的一小部分无效,其中包含一个项目或其中一个部分的图纸? (例如,包含一行文本或位图的矩形).
>我们如何在Draw Item中处理这样一个选择性的无效矩形?如果可以将整数作为Refresh或invalidate的一部分传递,我可以在DrawItem中使用它来确定要刷新的内容.
>有没有办法找到一个项目在TListBox上是否可见(按索引)?

提前致谢!

解决方法

您可以使用 InvalidateRect api使窗口的一部分无效.要查找项目占用的区域,可以使用ListBox的 ItemRect方法.例如,使第4项无效:

var
  R: TRect;
begin
  R := ListBox1.ItemRect(3);
  InvalidateRect(ListBox1.Handle,@R,True);
end;

(或’False’为’InvalidateRect’的’bErase’,请参阅其文档).要使位图或文本无效,请在传递给InvalidateRect之前相应地修改矩形.

您无法传递索引或任何类型的用户数据来刷新或无效.在绘画例程中,您必须根据位置确定要绘制的项目,或者如果绝对必要则使用全局变量.但是你不需要它,如果你只使一个项目的一部分无效,OnDrawItem只会被调用那个项目.在任何情况下,不要过于担心绘制非无效项目,因为在更新区域之外不会有任何实际绘图,您将不会有任何显着的性能损失(参见第3段here).

要确定某个项目是否可见,您将从顶部的第一个可见项目开始,并将连续项目的高度添加到控件的ClientHeight.顶部项目位于TopIndex.如果项目的高度已修复,您已知道最多可见多少项目.如果不是,你需要总结它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读