如何在VirtualTreeView中修复EStackOverflow?

时间:2013-07-31 08:58:35

标签: delphi stack-overflow virtualtreeview

有时我的项目中出现了EStackOverflow异常。我使用Delphi 2010和最新版本的VirtualTreeView。 Eurekalog生成的报告包含如下无限循环:

(这是bugreport的“调用堆栈”部分的一部分)

SetNodeHeight            
MeasureItemHeight      
GetNodeHeight          
GetDisplayRect         
InvalidateToBottom     
SetNodeHeight          
MeasureItemHeight
GetNodeHeight          
GetDisplayRect         
InvalidateToBottom     
SetNodeHeight          
MeasureItemHeight      
GetNodeHeight          
GetDisplayRect       

所有这些行都在VirtualTrees.pas中,VirtualTreeView的内部模块

screenshot

附加到控件的事件处理程序是:

  • TreeChange
  • TreeCollapsing
  • TreeFocusChanging
  • TreeFreeNode
  • TreeGetHint
  • TreeMeasureItem

procedure TTrainingForm.TreeMeasureItem(Sender: TBaseVirtualTree;  
  TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer);  
begin  
  inherited;  
  if Sender.MultiLine[Node] then  
  begin  
    try  
      TargetCanvas.Font := Sender.Font;  
      NodeHeight := TVirtualStringTree(Sender).  
         ComputeNodeHeight(TargetCanvas, Node, 0) + 4;  
    except  
      NodeHeight := 24;  
    end;  
  end  
end;  

我无法重现错误,但有时会在多个网站中发生错误。

如何修复或解决此问题?

1 个答案:

答案 0 :(得分:3)

TBaseVirtualTree.SetNodeHeight()中,只会输入函数正文if Node.NodeHeight <> Value。如果在OnMeasureItem事件处理程序中每次为一个节点提供不同的值,那么进入此循环似乎是可能的。作为第一个测试,在此处使用常量值并查看堆栈溢出是否消失。如果是这样,请为计算的项目高度进行调试输出,并仔细检查它们是否对节点具有确定性。如果没有,这就是问题的根源。然后降低OnMeasureItem事件处理程序中代码的复杂性,找出罪魁祸首。