Delphi - 当表单的ComponentCount递减时,如何中断

时间:2011-04-28 01:36:28

标签: delphi components toolbar delphi-2006 outofrangeexception

以下代码从Toolbar2000转载。它是从INI文件中读取工具栏位置和停靠状态的例程的一部分。我在初始化期间称这个例程。下面的代码迭代主窗体上的所有组件(OwnerComponent)并加载它找到的任何工具栏的设置。

for I := 0 to OwnerComponent.ComponentCount-1 do begin
  ToolWindow := OwnerComponent.Components[I];  //  <------------------------
....

这个迭代需要一些时间(秒 - 表单上有1500多个组件)并且我在显示的点处得到范围错误。我已经确定在执行此循环时正在从主窗体的组件中删除一个或多个项目,因此一旦发生这种情况,最终循环会尝试访问一个超过数组末尾的项目(可能最好将其编码为一个“downto”for循环来防止这种情况。)

无论如何,我需要找出主要表单丢失组件的位置。谁能给我任何关于如何做到这一点的Delphi 2006调试技巧?我不希望在我的程序中释放任何主要表单组件。

更新

我发现当我在设计时重新定位工具栏的默认停靠位置时,我无意中将其停靠在另一个工具栏上,而不是另一个工具栏所在的停靠站点。我通过从工具栏移除工具栏来解决问题它停靠在工具栏上并将其添加到Dock中。因此导致问题的安排是:

Dock 
  Toolbar 1
    Control 1
    Control 2
    Toolbar 2
      Control 3
      Control 4

并且解决方法就是安排他们:

Dock 
  Toolbar 1
    Control 1
    Control 2
  Toolbar 2
    Control 3
    Control 4

它仍然指向TB2k代码中的一个错误 - 人们会认为它应该能够处理嵌套的工具栏。

2 个答案:

答案 0 :(得分:6)

除了Lieven的回答,您还可以使用debug dcu并在进入循环之前在TComponent.Destroy中设置断点。

在这两种情况下,您都需要检查调用堆栈,以查看要调用的调用/更改的来源。

关于断点的一篇非常有趣的文章是由Cary Jensen撰写的:http://caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html

答案 1 :(得分:3)

每当计数发生变化时,您必须在@Self.FComponents.FCount添加data breakpoint才能中断。

  • ComponentCount是一个返回GetComponentCount
  • 值的属性
  • GetComponentCount返回FComponents.Count
  • FComponentsTList个实例,其中包含私有FCount变量。