Delphi - Как мне разбить, когда значение ComponentCount формы уменьшается - PullRequest
4 голосов
/ 28 апреля 2011

Код ниже воспроизводится с Toolbar2000. Это часть процедуры, которая считывает позиции панели инструментов и состояния стыковки из файла INI. Я называю эту процедуру во время инициализации. Этот код ниже выполняет итерацию по всем компонентам в главной форме (OwnerComponent) и загружает настройки любых панелей инструментов, которые он находит.

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

Эта итерация занимает некоторое время (секунды - в форме 1500 с лишним компонентов), и в указанной точке я получаю ошибку диапазона. Я удостоверился, что один или несколько элементов сбрасываются из компонентов основной формы во время выполнения этого цикла, поэтому в конце концов цикл пытается получить доступ к одному за концом массива, как только это произошло (предположительно, было бы лучше закодировать это как цикл «вниз» для предотвращения этого).

В любом случае, мне нужно выяснить, где основная форма теряет компонент. Кто-нибудь может дать мне какие-либо советы по отладке Delphi 2006 о том, как это сделать? Я не ожидал, что в этой точке моей программы будут освобождены какие-либо основные компоненты формы.

UPDATE

Я обнаружил, что, когда я переставил стандартную позицию панели инструментов во время разработки, я случайно прикрепил ее к другой панели инструментов, а не к месту док-станции, на котором находилась другая панель инструментов. Я исправил проблему, удалив панель инструментов с панели инструментов. панель инструментов, в которую он был закреплен, и вместо этого добавил его в док. Таким образом, договоренность, которая вызвала проблему, была:

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 ]

6 голосов
/ 28 апреля 2011

В дополнение к ответу Ливена, вы также можете использовать debug dcu и установить точку останова в TComponent.Destroy непосредственно перед тем, как войти в цикл.

В обоих случаях вам нужно будет проверить стек вызовов, чтобы увидеть, гдеисходящий вызов / изменение для подсчета.

Очень интересная статья о контрольных точках была написана Кэри Дженсеном: http://caryjensen.blogspot.com/2010/08/breakpoints-with-side-effects.html

3 голосов
/ 28 апреля 2011

Вам нужно будет добавить точку останова данных в @Self.FComponents.FCount, чтобы разрывать ее при изменении количества.

  • ComponentCount - это свойство, которое возвращает значение из GetComponentCount
  • GetComponentCount возвращает FComponents.Count.
  • FComponents - это экземпляр TList с закрытой переменной FCount.
...