Przecież TCheckBox to TControl więc nie wiem po co iterować po wszystkich komponentach jak można tylko po kontrolkach. Błędem w tym kodzie jest użycie ComponentCount zamiast ControlCount. Oczywiście trzeba też pobierać kontrolki a więc Controls[i] a nie Components[i].
Nie do tego te dwie listy służą. Nie chodzi o to z której klasy dany komponent dziedziczy, a o to, gdzie znajduje się dany komponent (w czym jest osadzony) i kto odpowiada za jego automatyczne zwolnienie, a więc o Parent i Owner.
W dużym skrócie:
-
Foo.Controls — zawiera listę komponentów, dla których Foo jest parentem. Z listy tej korzystamy wtedy, gdy chcemy uzyskać referencje wszystkich komponentów, które są osadzone wewnątrz Foo i jest to osadzenie pierwszego poziomu.
Jeśli np. formularz zawiera GroupBox, a w nim znajduje się Button, to lista Controls formularza będzie zawierać GroupBox (pierwszy poziom osadzenia), ale nie będzie zawierać Button (drugi poziom osadzenia). Aby uzyskać dostęp do Button, trzeba wejść w listę GroupBox.Controls.
-
Foo.Components — zawiera listę komponentów, dla których Foo jest ownerem. Z tej listy korzystamy wtedy, gdy chcemy mieć dostęp do wszsytkich komponentów zwalnianych automatycznie przez Foo. najczęściej używa się tej listy do iterowania po wszystkich komponentach formularza, bez względu na to czy i gdzie są osadzone.
Jeśli np. formularz zawiera GroupBox, a w nim znajduje się Button, to lista Components formularza będzie zawierać referencje do GroupBox i Button (poziom osadzenia nie ma znaczenia). Natomiast lista GroupBox.Components będzie pusta, nieważne ile komponentów jest w nim osadzonych. W przypadku tworzenia formularzy w designerze, obiekt formularza będzie wyłącznym ownerem wszystkich wyklikanych komponentów.
Przykładowy formularz:

Drzewo osadzenia komponentów formularza:
Kopiuj
Form1
GroupBox1
CheckBox1
CheckBox2
CheckBox3
GroupBox2
Button1
Button2
GroupBox3
Button3
Zawartość list Controls i Components formularza i komponentów okienkowych:
Kopiuj
Form1.Controls GroupBox1, GroupBox2
Form1.Components GroupBox1, CheckBox1, CheckBox2, CheckBox3, GroupBox2, Button1, Button2, GroupBox3, Button3 // cała zawartość formularza
GroupBox1.Controls CheckBox1, CheckBox2, CheckBox3
GroupBox1.Components // nic
GroupBox2.Controls Button1, Button2, GroupBox3
GroupBox2.Components // nic
GroupBox3.Controls Button3
GroupBox3.Components // nic
Dla checkboxów i przycisków, listy Controls również są dostępne, jednak będą one puste, dlatego że nie obsługują osadzania w sobie subkomponentów. Aby osadzanie było możliwe, w do zbioru flag z pola TControl.FControlStyle należy dodać flagę csAcceptsControls, a ta jest usuwana ze zbioru w konstruktorach klas komponentów, które mają osadzania nie obsługiwać (czyli np. w TCheckBox i TButton).
Myślę, że teraz wszystko powinno być jasne. ;)