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.
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
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.
精彩评论