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

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

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


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

delphi - 如何在VirtualTreeView中修复EStackOverflow?-LMLPHP

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


树变
树崩溃
树焦点变化
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;


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

如何解决此问题?

最佳答案

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

07-25 20:19