![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
При переключении между чекбоксами - ошибка Stack overflow. [D7, WinXP]
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]Хотелось бы все же ответ на мой предыдущий вопрос по форуму. Спасибо.