Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
14-05-2008 06:34
Geo:
Цитирую себя, любимого:
"Зависит от компилятора и кода внутри цикла" :D
Протест принимается... :)
Sega-Zero:
У копмонентов есть свойство ComponentIndex, определяющее его индекс в массиве компонентов. Обход идет тупо по массиву в соответствии с ComponentIndex
Да, вы правы... Достаточно было заглянуть в help:
TComponent.ComponentIndex
Use ComponentIndex when iterating through the Components list of the component’s owner to perform some action on owned components. It can be used in conjunction with ComponentCount. ComponentIndex is used internally for iterative assignment procedures.
Geo:
>>> Если мне не изменяет память, их порядок совпадает с порядком обхода по Tab, т.е задаётся по TabOrder
Изменяет. Sega-Zero прав. Вспоминте, что при визуальном проектировании форм мы можем выполнять для контролов BringToFront (или что-то в этом роде). При этом TabOrder не изменяется.
Так и есть...
Для того, чтобы всё это продемонстрировать наглядно, сделаем тестовый пример:
procedure ShowControls(AParent: TWinControl);
var
i: Integer;
S: String;
begin
for i := 0 to AParent.ControlCount-1 do
if AParent.Controls[i] is TWinControl then
with AParent.Controls[i] as TWinControl do
S := S + Format('[%d] %d %s'#13#10, [i, TabOrder, Name])
else
with AParent.Controls[i] do
S := S + Format('[%d] - %s'#13#10, [i, Name]);
ShowMessage(S);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowControls(Self);
end;
end.
Порядок вставки компонентов виден из объявления. Далее последовательно выполняем действия в дизайнере, запускаем и получаем на выходе:
Таким образом видим, что:
1. Неоконные контролы группируются в начале.
2. Изменение TabOrder не влияет на положение контрола в списке Controls (т.е. на ComponentIndex)
3. Bring to front перемещает контрол в конец списка Controls
4. Send to back перемещает контрол в начало списка Controls, но после неоконных контролов.
14-05-2008 04:45 | Комментарий к предыдущим ответам
>>> Ну, я бы не согласился. Порядок не гарантируется тогда, когда пользователю, по мнеию компилятора это по барабану, т.е если внутни цикла переменная цикла не используется
Цитирую себя, любимого:
"Зависит от компилятора и кода внутри цикла" :D
>>> Если мне не изменяет память, их порядок совпадает с порядком обхода по Tab, т.е задаётся по TabOrder
Изменяет. Sega-Zero прав. Вспоминте, что при визуальном проектировании форм мы можем выполнять для контролов BringToFront (или что-то в этом роде). При этом TabOrder не изменяется.
14-05-2008 02:44 | Комментарий к предыдущим ответам
>>> В общем случае цикл FOR не гарантирует тот или иной порядок выполнения.
Ну, я бы не согласился. Порядок не гарантируется тогда, когда пользователю, по мнеию компилятора это по барабану, т.е если внутни цикла переменная цикла не используется, например, просто выдаётся 10 "бипов", а for используется только для отсчёта их количества. Если же используется, то порядок определяется вполне однозначно. Думаю, одной из причин жёсткого требования, что переменная цикла должна быть именно локальной переменной, является необходимость отслеживания её использования внутри цикла. И как следствие "иногда неопределённого порядка" - неопределённость значения вне цикла.
Но вопрос был не об этом... Он был о порядке расположения контролов в списке Controls... Если мне не изменяет память, их порядок совпадает с порядком обхода по Tab, т.е задаётся по TabOrder, который первоначально совпадает с порядком создания контролов.
Зависит от компилятора и кода внутри цикла. В общем случае цикл FOR не гарантирует тот или иной порядок выполнения. А пользоваться эмпирически полученным опытом -- не самый лучший вариант. Так что если для Вас порядок жизненно важен, то лучше все же поступать так
var
i : Integer;
begin
i:=0;
while i < ControlCount do
begin
// обрабатываем Controls[i]
Inc(i);
end;
end;
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.