Цикл по ВСЕМ контролам
Модератор: Модераторы
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Цикл по ВСЕМ контролам
Не могу сообразить, как же пройтись по ВСЕМ контролам, скажем, TTabSheet-a, в том числе и тем, которые в подчиненных боксах и панелях. Разве что делать обход по принципу дерева каталогов?
Зачем надо? Ну, хочу, например, чтобы у всех edit-ов в hint добавилась их максимальная длина - при вписывании ее вручную можно потом забыть исправить, если она изменится.
Зачем надо? Ну, хочу, например, чтобы у всех edit-ов в hint добавилась их максимальная длина - при вписывании ее вручную можно потом забыть исправить, если она изменится.
- alexs
- долгожитель
- Сообщения: 4069
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
Код: Выделить всё
for I:=0 to Form1.ControlCount-1 do;
Form1.Controls[i].Hint:='bla-bla';
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
А вот ни фига!
Прежде чем ответить специально проверил: так находятся только контролы, подчиненные самой форме, но не те, что подчиняются ее подчиненным. Например, мне не удалось таким способом добраться до радиокнопок в радиобоксе. Конкретно по моей форме (см. рисунок) находятся всего четыре контрола: пейджконтрол, статусбар, тулбар и прогресс (маленький прямоугольник в правой части тулбара).
Так что вопрос остается в силе: как посмотреть контролы, подчиненные не самой форме?
Прежде чем ответить специально проверил: так находятся только контролы, подчиненные самой форме, но не те, что подчиняются ее подчиненным. Например, мне не удалось таким способом добраться до радиокнопок в радиобоксе. Конкретно по моей форме (см. рисунок) находятся всего четыре контрола: пейджконтрол, статусбар, тулбар и прогресс (маленький прямоугольник в правой части тулбара).
Так что вопрос остается в силе: как посмотреть контролы, подчиненные не самой форме?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Код: Выделить всё
for i:=0 to GroupBox1.ControlCount-1 do
if GroupBox1.Controls[i] is TLabel then
(GroupBox1.Controls[i] as Tlabel).Caption:='1'; Если нужно пройти все контролы, в том числе находящиеся на панелях или групбоксах, то пишем рекурсивную функцию проходящую все контролы формы и передающую их в качестве параметра этой же функции, для поиска подчиненных контролов.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
B4rr4cuda писал(а):пишем рекурсивную функцию
Так я и знал
у меня все контролы проходятся. При чем мне приходится специально выделять те которые на Panelи if (Form1.Components[i] as TControl).Parent = Panel1 then .... А в RadioGrupBox и ему подобных контрлы созданы (скорее всего) в них, а не в форме, т.е. RadioButton := RadioButton.Create(RadioGrupBox); RadioButton.Parent := RadioGrupBox;. Самый верный выход из положения видится, если RadioButton-ы создавать на отдельных панелях, а не в GrupBox-ах. Тогда он будет определяться в массиве контрлов принадлежащих Form-е и управляемый Panel-ью.
Попробуй использовать:
for i := 0 to pred(TForm1.ComponentCount) do
(Form1.Components[i] as Tcontrol).AnyWhat := AnyWhat;
Попробуй использовать:
for i := 0 to pred(TForm1.ComponentCount) do
(Form1.Components[i] as Tcontrol).AnyWhat := AnyWhat;
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Контролы или компоненты?VirtUX писал(а):у меня все контролы проходятся
Кажется понял, в чем дело. На этой конкретной форме насчиталось 4 контрола и 98 компонентов. Цикл по form.components дал мне то, что я хотел, вроде бы...
Вот именно, что "вроде" - в "инспекторе объектов" как раз 98 штук и насчитал. В это число не вошли созданные в рантайме пара десятков радиокнопок
(смотрел в методе OnShow, когда эти кнопки уже созданы)
Добавлено спустя 3 минуты 52 секунды:
Разве что, при создании чего-то в рантайме вызывать form.addControl?
Только что проверил. RadioGroup - определяется как единый компонент. Внутренностями нужно управлять через свойства его. А вот GroupBox берет на себя только свойство Parent, поэтому все внутренности видны. Ставь RadioButton-ы в GroupBox и будет тебе счастье 
Добавлено спустя 3 минуты 12 секунд:
Я же написал Хочешь - это будет контрол, убери as TControl будет тебе компонент.
Добавлено спустя 3 минуты 12 секунд:
Troublemaker писал(а):Контролы или компоненты?VirtUX писал(а):у меня все контролы проходятся
Я же написал
Код: Выделить всё
Form1.Components[i] as TСontrol- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Именно так и делаю. Кнопки, которые созданы в дизайнере, видны как отдельные контролы/компоненты. Те, которые созданы в рантайме, не видны.VirtUX писал(а):Ставь RadioButton-ы в GroupBox и будет тебе счастье
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
alexs писал(а):имя присваиваеш уникальное?
Разумеется. Вот так, как мы когда-то обсуждали в теме "передача типа как параметра". Я не стал возиться с классами - раньше никогда сам их не делал, и боюсь сейчас "зарыться", поэтому "рулит" старое доброе процедурное программирование.
car и har - массивы строк для caption и hint.
BuName - шаблон для создания имен, например
Код: Выделить всё
procedure TEditForm.CreateButtons(car,har:TStrArray;var bar:array of TRadioButton;BuName:string;POw:TGroupBox;ONC:TNotifyEvent);
var i:Integer;
begin
for i:=Low(car) to High(car) do begin
bar[i]:=TRadioButton.Create(POw);
with bar[i] do begin
Caption:=car[i];
Hint:=har[i];
Width:=cDefRButHeight;
Height:=cDefRButHeight;
Visible:=true;
Tag:=ord(i);
Name:=BuName+Format('%2.2D',[i]);
Checked:=false;
Parent:=POw;
Onclick:=ONC;
TabStop:=false;
end;
end;
end;
Вот примеры использования из реального исходника:
Код: Выделить всё
CreateButtons(TStrArray(cCDKName),TStrArray(cCDKHint),CDKButtons,'CDKButton',CollDestKindBox,@CollKindChanged);
CreateButtons(TStrArray(cQKname),TStrArray(cQKhint),QKButtons,'QKButton',QKindBox,@QKindChanged);
CreateButtons(TStrArray(cEKname),TStrArray(cEKhint),EKButtons,'EKButton',ExamKindBox,@EKindChanged);Соответственно, имена получаются типа CDKButton00, QKButton03 и т.п.
Единственное сомнение, ибо этот момент как-то не очень отражен в документации, это то, что я при создании указываю овнером тот групбокс, куда кнопки должны вставляться. Может там надо указывать форму как овнера, а групбокс только как родителя?
Добавлено спустя 22 минуты 56 секунд:
Сейчас изменил немного процедуру создания кнопок:
Код: Выделить всё
bar[i]:=TRadioButton.Create(EditForm);Не нравится тем, что я в описании КЛАССА обращаюсь к конкретной переменной, не являющейся пропертью этого класса, и не могу вспомнить, к чему относится self - к экземпляру класса или к чему-то другому? То есть, если вместо Create(EditForm) я напишу Create(Self), кто станет овнером?
bar[i]:=TRadioButton.Create(EditForm);
Это как раз-таки правильно. В конструктор передается компонент-владелец (Owner). В каждом компоненте есть массив подчиненных компонентов, для которых он выступает владельцем. TForm - этот тоже компонент. Когда бросаешь компонент на форму, то Owner'ом выступает форма. Это нужно, чтобы при удалении формы, ее деструктор смог пройти по всем компонентам и освободить их.
Self указывает на текущий экземпляр, поэтому код
Будет полностью эквивалентен:
И даже правильнее, т.к. потенциально можно создать несколько экземпляров форм, а первый пример сошлется только на одну.
Это как раз-таки правильно. В конструктор передается компонент-владелец (Owner). В каждом компоненте есть массив подчиненных компонентов, для которых он выступает владельцем. TForm - этот тоже компонент. Когда бросаешь компонент на форму, то Owner'ом выступает форма. Это нужно, чтобы при удалении формы, ее деструктор смог пройти по всем компонентам и освободить их.
Self указывает на текущий экземпляр, поэтому код
Код: Выделить всё
procedure TEditForm.Add;
begin
bar:=TRadioButton.Create(EditForm);
end;Будет полностью эквивалентен:
Код: Выделить всё
procedure TEditForm.Add;
begin
bar:=TRadioButton.Create(Self);
end;И даже правильнее, т.к. потенциально можно создать несколько экземпляров форм, а первый пример сошлется только на одну.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
dymken писал(а):первый пример сошлется только на одну
ВотЪ-вотЪ! Поэтому мне и не понравилось, то, что не понравилось.
