Delphi - 当表单的 ComponentCount 递减时如何中断
下面的代码是从 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 代码中的一个错误 - 人们会认为它应该能够处理嵌套工具栏。
The code below is reproduced from Toolbar2000. It is part of routine that reads toolbar positions and dock states from an INI file. I call this routine during initialisation. This code below is iterating through all the components on the main form (OwnerComponent) and loading the settings of any toolbars it finds.
for I := 0 to OwnerComponent.ComponentCount-1 do begin
ToolWindow := OwnerComponent.Components[I]; // <------------------------
....
This iterating takes some time (seconds - there are 1500-odd components on the form) and I'm getting a range error at the point shown. I have ascertained that one or more items is being shed from the main form's components while this loop is executing, so eventually the loop tries to access one past the end of the array once this has happened (presumably it would be better to code this as a "downto" for-loop to prevent this).
Anyway, I need to find out where the main form is losing a component. Can anybody give me any Delphi 2006 debugging tips on how to do this? I wouldn't expect any main form components to be freed at this point in my program.
UPDATE
I found that when I had repositioned a toolbar's default dock position at design-time I had inadvertently docked it onto another toolbar, rather than the dock site that the other toolbar was in. I fixed the problem by removing the toolbar from the toolbar it was docked in and adding it to the dock instead. So the arrangement that caused the problem was:
Dock
Toolbar 1
Control 1
Control 2
Toolbar 2
Control 3
Control 4
and the fix was to arrange them thus:
Dock
Toolbar 1
Control 1
Control 2
Toolbar 2
Control 3
Control 4
It still points to a bug in the TB2k code though - one would assume it should be able to handle nested toolbars.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除了 Lieven 的答案之外,您还可以使用 debug dcu 并在进入循环之前在 TComponent.Destroy 中设置断点。
在这两种情况下,您都需要检查调用堆栈以查看计数的调用/更改来自何处。
Cary Jensen 写了一篇关于断点的非常有趣的文章: http:// /caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html
In addition to Lieven's answer, you could also use debug dcu's and set a breakpoint in TComponent.Destroy just before you enter the loop.
In both cases you will need to examine the call stack to see where the call/change to count is coming from.
A very interesting article on breakpoints was written by Cary Jensen: http://caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html
您必须在
@Self.FComponents 添加数据断点 .FCount
每当计数发生变化时就会中断。ComponentCount
是一个从GetComponentCount
返回值的属性,GetComponentCount
返回FComponents.Count
。FComponents
是一个具有私有FCount
变量的TList
实例。You'll have to add a data breakpoint at
@Self.FComponents.FCount
to break whenever the count changes.ComponentCount
is a property that returns the value fromGetComponentCount
GetComponentCount
returnsFComponents.Count
.FComponents
is aTList
instance that has a privateFCount
variable.