gpt4 book ai didi

delphi - 如何有选择地使Owner Drawn TListBox的 Canvas 无效?

转载 作者:行者123 更新时间:2023-12-03 15:20:28 29 4
gpt4 key购买 nike

我有一个所有者绘制的 TListBox (lbVirtualOwnerDraw),其内容会动态更新(每秒最多可以有 10 次更新)。列表框中一次最多可以包含 300 个项目。每个项目可能有大约 5 行文本和与其关联的图像。每当刷新某个项目时,我都必须刷新(或无效)TListBox,以便 VCL 框架调用 ListBoxDrawItem。但由于所有多余的重新绘制,这会对整体性能产生不利影响。所以我的问题是:

  1. 是否有办法仅使包含一个项目或其一个部分的绘图的 Canvas 的一小部分无效? (例如,包含一行文本或位图的矩形)。

  2. 我们如何在 Draw Item 中处理这样一个选择性无效的矩形?如果可以传递一个整数作为刷新或无效的一部分,我可以在 DrawItem 中使用它来确定要刷新的内容。

  3. 有没有办法查找某个项目在 TListBox 上是否可见(通过索引)?

提前致谢!

最佳答案

您可以使用InvalidateRect api 使窗口的一部分无效。要查找项目占用的区域,您可以使用 ItemRect列表框的方法。例如使第四项无效:

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

(或“False”作为“InvalidateRect”的“bErase”,请参阅其文档)。要仅使位图或文本无效,请在传递到 InvalidateRect 之前相应地修改矩形。


您不能传递索引或任何类型的用户数据来刷新或失效。在绘画例程中,您必须根据位置确定要绘制的项目,或者在绝对必要时使用全局变量。但您不需要这样做,如果您仅使一个项目的一部分无效,则只会为该项目调用 OnDrawItem 。无论如何,不​​要太担心绘制非无效项,因为更新区域之外不会有任何实际绘制,因此不会对性能造成任何重大影响(请参阅第 3 段 here )。


要确定某个项目是否可见,您可以从顶部的第一个可见项目开始,然后添加连续项目的高度,直到控件的 ClientHeight。顶部项目位于TopIndex 。如果项目的高度是固定的,您就已经知道最多有多少个项目是可见的。如果没有,您需要总结它们。

关于delphi - 如何有选择地使Owner Drawn TListBox的 Canvas 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5560088/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com