Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

При переключении между чекбоксами - ошибка Stack overflow. [D7, WinXP]


Страницы:   1 2 3

Dr.Andrew ©   (2008-08-26 20:22:00) 

Добрый вечер!

Тестировано на Delphi 2007 win32 и Windows Vista Home Basic.
Проблемы с компонентом TCheckBox.
Вот два варианта кода:

procedure TForm1.CheckBox1Click(Sender: TObject);
// var i : Integer;
begin
{ for i := 0 to GroupBox1.ControlCount-1 do
begin
if TComponent(Sender).Tag = i then
(GroupBox1.Controls[i] as TCheckBox).Checked := True
else
(GroupBox1.Controls[i] as TCheckBox).Checked := False;
end; }

if Sender = CheckBox1 then
begin
CheckBox1.Checked := True;
CheckBox2.Checked := False;
CheckBox3.Checked := False;
CheckBox4.Checked := False;
end
else
if Sender = CheckBox2 then
begin
CheckBox1.Checked := False;
CheckBox2.Checked := True;
CheckBox3.Checked := False;
CheckBox4.Checked := False;
end
else
if Sender = CheckBox3 then
begin
CheckBox1.Checked := False;
CheckBox2.Checked := False;
CheckBox3.Checked := True;
CheckBox4.Checked := False;
end
else
if Sender = CheckBox4 then
begin
CheckBox1.Checked := False;
CheckBox2.Checked := False;
CheckBox3.Checked := False;
CheckBox4.Checked := True;
end;
end;


Финал один при переключении между чекбоксами выдает компиллятор следующую ошибку:

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EStackOverflow with message 'Stack overflow'.
---------------------------
Break Continue Help
---------------------------

В чем проблема?

Спасибо.


Германн   (2008-08-27 01:06:00) [21]


> Сообщение 'Stack overflow' совершенно однозначно описывает
> причину проблемы.
>
> > Да, но на делфи 7 все было нормально, а в делфи 2007 вот
> > такая проблема.
>
>
> В D7 тоже самое.

По-моему я как-то приводил тут пример подобной бесконечной рекурсии, но там даже 'Stack overflow' было не дождаться. Слишком много времени занимала перерисовка грида.


Dr.Andrew   (2008-08-27 00:24:00) [22]

Все работает! Спасибо {RASkov}. Второй вариант супер!


Dr.Andrew   (2008-08-27 00:20:00) [23]

Проверил второй вариант ([19]), но он не работает, ошибки тоже нет, просто чекбоксы отмечаются, но не отключаются другие. В чем ошибка?


Dr.Andrew   (2008-08-26 23:49:00) [24]

Спасибо. полный разбор вопроса. Спасибо!


{RASkov}   (2008-08-26 22:30:00) [25]

> [16] Dr.Andrew   (26.08.08 22:10)

Попробуй вот такой вариант:
 CheckBox1.OnClick:=nil;
 CheckBox2.OnClick:=nil;
 CheckBox3.OnClick:=nil;
 CheckBox4.OnClick:=nil;
 CheckBox1.Checked := False;
 CheckBox2.Checked := False;
 CheckBox3.Checked := False;
 CheckBox4.Checked := False;
 TCheckBox(Sender).Checked:=True;
 CheckBox1.OnClick:=CheckBox1Click;
 CheckBox2.OnClick:=CheckBox1Click;
 CheckBox3.OnClick:=CheckBox1Click;
 CheckBox4.OnClick:=CheckBox1Click;

Или вот такой если все чеки на одном паренте и у них один обработчик OnClick:
procedure SetChecks(APar: TWinControl; Check: TCheckBox; AllOnClick: TNotifyEvent);
var N: Integer;
begin
 for N:=0 to APar.ControlCount-1 do
  if APar.Controls[N] is TCheckBox then begin
   TCheckBox(APar.Controls[N]).OnClick:=nil;
   TCheckBox(APar.Controls[N]).Checked:=False;
  end;
 Check.Checked:=True;
 for N:=0 to APar.ControlCount-1 do
  if APar.Controls[N] is TCheckBox then
   TCheckBox(APar.Controls[N]).OnClick:=AllOnClick;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
 SetChecks(Self, TCheckBox(Sender), CheckBox1Click);
end;

Можно еще много разных вариантов придумать, но может стоит присмотреться к [3]?


Loginov Dmitry   (2008-08-26 22:29:00) [26]

> В чем проблема?


Сообщение 'Stack overflow' совершенно однозначно описывает причину проблемы.

> Да, но на делфи 7 все было нормально, а в делфи 2007 вот
> такая проблема.


В D7 тоже самое.


{RASkov}   (2008-08-26 22:16:00) [27]

> Кстати, так не работает.

Именно так не будет, но направление есть, нужно только всем "отключить", а затем всем "включить" данный обработчик...
 CheckBox1.OnClick:=nil;
 CheckBox2.OnClick:=nil;
 CheckBox3.OnClick:=nil;
 CheckBox4.OnClick:=nil;
тут код из [0]
 CheckBox1.OnClick:=CheckBox1Click;
 CheckBox2.OnClick:=CheckBox1Click;
 CheckBox3.OnClick:=CheckBox1Click;
 CheckBox4.OnClick:=CheckBox1Click;


Dr.Andrew   (2008-08-26 22:10:00) [28]

student

Кстати, так не работает.


Dr.Andrew   (2008-08-26 22:02:00) [29]

Спасибо


{RASkov}   (2008-08-26 21:46:00) [30]

> [12] Dr.Andrew   (26.08.08 21:41)

Тогда пожалуйста, приходите ещё.
:о)


student   (2008-08-26 21:45:00) [31]

procedure TForm1.CheckBox1Click(Sender: TObject);
// var i : Integer;
begin
if Sender = CheckBox1 then
begin
  CheckBox1.OnClick := nil;
CheckBox1.Checked := True;
CheckBox2.Checked := False;
 // ...
end;
  CheckBox1.OnClick := CheckBox1Click
end;


Dr.Andrew   (2008-08-26 21:41:00) [32]

Спасибо. Я только за взаимную вежливость.


{RASkov}   (2008-08-26 21:40:00) [33]

> [8] Dr.Andrew   (26.08.08 21:30)
> Нет не вру - может ккие-то другие процессы этому мешали,
> но проект компилированный в делфи 7 работал с подобной
> формой процедуры прогона чекбоксов работал нормально

Ну не может он нормально работать... логически подумать даже с акциями должно быть переполнение стека...
Вот если предварительно отключать OnClick затем вся эта манипуляция и затем назад онклик вернуть, тогда - да. А так - ну не может :)


{RASkov}   (2008-08-26 21:35:00) [34]

> [8] Dr.Andrew   (26.08.08 21:30)
> Только не стоит употреблять такую лексику как "Врешь".

:) Ну сорри.... я вот такой вот вредный) Могу вообще не отвечать в твоих ветках :)


{RASkov}   (2008-08-26 21:33:00) [35]

Т.е. в [7] я хотел сказать, что не сработает в том случае, когда мы выставляем чекед который текущий в данный момент в контроле...
Т.е. Вот так
в чеке установлена галка, тогда
Checked := True;  //НЕ вызовет OnClick
Checked := False; // Вызовет OnClick
в чеке НЕ установлена галка, тогда
Checked := True;  //Вызовет OnClick
Checked := False; //НЕ вызовет OnClick


Dr.Andrew   (2008-08-26 21:30:00) [36]

Спасибо. Только не стоит употреблять такую лексику как "Врешь". Нет не вру - может ккие-то другие процессы этому мешали, но проект компилированный в делфи 7 работал с подобной формой процедуры прогона чекбоксов работал нормально. Спасибо.


{RASkov}   (2008-08-26 21:22:00) [37]

> [6] TStas ©   (26.08.08 21:14)
> Нет! Не всегда программное переключение CheckBox'а вызывает
> OnClick!

Эт как это? :)
Да, может быть с экшенами что-то связано, но если без них то всегда.
Не сработает в том случае, если мы программно выставляем CheckBox.Checked := True; а в нем до этого была установлена галка - тогда - да, не сработает.... но в "нашем" случае это явно не так.... Хотя пока не известно с акциями там как дела, но.... пока все именно так как в [1] :)


TStas   (2008-08-26 21:14:00) [38]

>Врешь.... переполнение везде будет с данным кодом.... Подробно в [1]
Нет! Не всегда программное переключение CheckBox'а вызывает OnClick! Я сам до сих пор не понял, почему. А вот у RadioGroup, о котором Зотов верное очень сказал, что именно его функциональность используется, ИМХО, всегда.
Мне кажется, что это связано с тем, что CheckBox - это лишь обёрка к аналогичному объекту Виндов, а они, как известно, сильно различаются друг от друга.


{RASkov}   (2008-08-26 21:08:00) [39]

> [2] Dr.Andrew   (26.08.08 20:53)
> Да, но на делфи 7 все было нормально

Врешь.... переполнение везде будет с данным кодом.... Подробно в [1])


Dr.Andrew   (2008-08-26 21:03:00) [40]

Хотелось бы все же ответ на мой предыдущий вопрос по форуму. Спасибо.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо