簡體   English   中英

如何有選擇地使Owner Drawn TListBox的畫布無效?

[英]How to selectively invalidate Owner Drawn TListBox's canvas?

我有一個所有者繪制TListBox(lbVirtualOwnerDraw),其內容得到動態更新(一秒鍾內可以有多達10個更新)。 一次最多可以在列表框中放置300個項目。 每個項目可能有大約5行文本和與之關聯的圖像。 每當刷新一個項目時,我都必須刷新(或使其無效)TListBox,以便VCL框架調用ListBoxDrawItem。 但由於所有冗余重新塗漆,這會對整體性能產生不利影響。 所以我的問題是:

  1. 有沒有辦法只使畫布的一小部分無效,其中包含一個項目或其中一個部分的圖紙? (例如,包含一行文本或位圖的矩形)。

  2. 我們如何在Draw Item中處理這樣一個選擇性的無效矩形? 如果可以將整數作為Refresh或invalidate的一部分傳遞,我可以在DrawItem中使用它來確定要刷新的內容。

  3. 有沒有辦法找到一個項目在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段)。


要確定某個項目是否可見,您將從頂部的第一個可見項目開始,並將連續項目的高度添加到控件的ClientHeight。 頂部項目位於TopIndex 如果項目的高度是固定的,您已經知道最多可以看到多少項目。 如果不是,你需要總結它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM