4

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

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

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

无论如何,我需要找出主窗体丢失组件的位置。任何人都可以给我任何有关如何执行此操作的 Delphi 2006 调试提示吗?我不希望此时在我的程序中释放任何主要表单组件。

更新

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

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 代码中的一个错误——人们会假设它应该能够处理嵌套的工具栏。

4

2 回答 2

6

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

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

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

于 2011-04-28T06:27:35.490 回答
3

您必须在计数更改时添加数据断点以中断。@Self.FComponents.FCount

  • ComponentCount是一个返回值的属性GetComponentCount
  • GetComponentCount返回FComponents.Count
  • FComponents是一个TList具有私有FCount变量的实例。
于 2011-04-28T06:07:53.403 回答