Delphi - Как мне прервать работу, когда количество компонентов в форме уменьшается
-
25-10-2019 - |
Вопрос
Приведенный ниже код воспроизведен из 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 - можно было бы предположить, что он должен уметь обрабатывать вложенные панели инструментов.
Решение
В дополнение к ответу Ливена, вы также можете использовать debug dcu и установить точку останова в TComponent .Уничтожьте непосредственно перед входом в цикл.
В обоих случаях вам нужно будет изучить стек вызовов, чтобы увидеть, откуда поступает вызов / изменение для подсчета.
Очень интересная статья о точках останова была написана Кэри Дженсеном: http://caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html
Другие советы
Вам нужно будет добавить точка останова данных в @Self.FComponents.FCount
прерываться всякий раз, когда изменяется счетчик.
ComponentCount
это свойство, которое возвращает значение изGetComponentCount
GetComponentCount
ВОЗВРАТFComponents.Count
.FComponents
являетсяTList
экземпляр, который имеет частныйFCount
переменная.