![]() |
| ||
|
|
Новости |
Поиск |
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
---------------------------
В чем проблема?
Спасибо.
Anatoly Podgoretsky (2008-09-01 16:12:00) [1]> {RASkov} (01.09.2008 15:29:41) [41]
Не надежно, если не моргаем, то экономии нет, а когда моргаем перерасход на включение - токовый удар.
Anatoly Podgoretsky (2008-09-01 16:11:00) [2]> Vlad Oshin (01.09.2008 13:20:40) [40]
Зато я серьезно, можешь сам посчитать
потнебляемая мощность 0,1 вт
В сутках 24 часа, в году 365 дней.
Это только на глаз кажется ничего, а если посчитать, то ого-го
{RASkov} (2008-09-01 15:29:00) [3]> [40] Vlad Oshin © (01.09.08 13:20)
> я ж прикольнулся
> когда моргаем, выключаем монитор :)
Класс :)))
Vlad Oshin (2008-09-01 13:20:00) [4]>Это ORD(True) могут быть разнымиясно.
PS
я ж прикольнулся
pss
> И выключаем Num Lock экономим электроэнергию
Пойдем дальше - когда моргаем, выключаем монитор :)
{RASkov} (2008-09-01 13:12:00) [5]> точно не помню, но так, (1=1), точно будет true
А разве True (т.е. Checked := True) может быть False? :)
Это ORD(True) могут быть разными...)
То что писать короче, да, но а компилятору теперь лишняя работа, хотя оптимизатор один фик заменит на булевые константы... имхо.
evvcom (2008-09-01 13:06:00) [6]
> 1. писать короче на 1 символ -> экономим место на диске :)
Да... Это серьезная экономия :))
> но так, (1=1), точно будет true
True тоже точно будет true :)
> еще про связанное с внутренним их представлением
Ну если такое написать Boolean(2), то можешь наступить на грабли :)
Anatoly Podgoretsky (2008-09-01 13:03:00) [7]> Vlad Oshin (01.09.2008 12:25:36) [36]
И выключаем Num Lock экономим электроэнергию
Vlad Oshin (2008-09-01 12:25:00) [8]
> evvcom © (01.09.08 12:05) [35]
1. писать короче на 1 символ -> экономим место на диске :)
2. тут проскакивала темка про константы булевы, точно не помню, но так, (1=1), точно будет true.
Во, блин, вообще не помню..
Короче что-то там от версии к версии, еще про связанное с внутренним их представлением,
вот так как-то.. что-то ..
:)
evvcom (2008-09-01 12:05:00) [9]
CheckBox1.Checked := 1=2;
:-) а True / False уже отменили?
Dr.Andrew (2008-08-28 21:41:00) [10]Спасибо. тоже очень интересное решение.
Vlad Oshin (2008-08-28 09:31:00) [11]
> Если один из чекбоксов был включен предварительно, то последний
> пример работает с запаздыванием
тогда вот, полная иммитация radioбулочек :)
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
procedure CheckBox1Click(Sender: TObject);
private
procedure ExtractedMethod;
{ Private declarations }
public
{ Public declarations }
end;
tb=class(TButtonControl);
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ExtractedMethod;
begin
CheckBox1.Checked := 1=2;
CheckBox2.Checked := 1=2;
CheckBox3.Checked := 1=2;
CheckBox4.Checked := 1=2;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
ExtractedMethod;
tb(sender).ClicksDisabled := 1=1;
ExtractedMethod;
tCheckBox(sender).Checked := 1=1;
end;
Германн (2008-08-28 01:11:00) [12]
> {RASkov} © (27.08.08 20:54) [29]
>
> > [28] MsGuns © (27.08.08 20:45)
>
> Ну и что :) Кстати, хороший вариант...)
>
У меня тоже был вариант. Вот только найти его в архивах на скорую руку не смог. (((
{RASkov} (2008-08-27 22:02:00) [13]> [30] Dr.Andrew (27.08.08 21:48)
> Если один из чекбоксов был включен предварительно, то последний
> пример работает с запаздыванием
Этому в принципе есть объяснение.
Так как OnClick вызовется для всех изначально включенных, помимо того который включаем - чекбоксов...
Из-за того что мы снимаем состояние чекед, вследствии чего снова вызывается данный обработчик онклик и дисаблим онклик вызвавшего чека....
Лучше в коде это отследить, чем понять что я тут понаписал :)
Так же себя поведет и код Влада....
Dr.Andrew (2008-08-27 21:48:00) [14]{RASkov}
Если один из чекбоксов был включен предварительно, то последний пример работает с запаздыванием.
Спасибо за помощь.
{RASkov} (2008-08-27 20:54:00) [15]> [28] MsGuns © (27.08.08 20:45)
Ну и что :) Кстати, хороший вариант...)
Итого у нас получилось:
type tb=class(TButtonControl);
procedure SetChecks(APar: TWinControl; Check: TCheckBox);
var N: Integer;
begin
tb(Check).ClicksDisabled:=True;
for N:=0 to APar.ControlCount-1 do
if APar.Controls[N] is TCheckBox then
TCheckBox(APar.Controls[N]).Checked:=False;
Check.Checked:=True;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
SetChecks(Panel1, TCheckBox(Sender));
end;
:)
MsGuns (2008-08-27 20:45:00) [16]>Vlad Oshin © (27.08.08 17:52) [27]
Ежики надели бронежилеты и продолжали лезть на кактус
;)
Vlad Oshin (2008-08-27 17:52:00) [17]
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
procedure CheckBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
tb=class(TButtonControl);
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
tb(sender).ClicksDisabled:=true;
CheckBox1.Checked := False;
CheckBox2.Checked := False;
CheckBox3.Checked := False;
CheckBox4.Checked := False;
tCheckBox(sender).Checked:=true;
end;
Dr.Andrew (2008-08-27 15:14:00) [18]Спасибо за помощь
MsGuns (2008-08-27 11:31:00) [19]ИМХО, для выбора варианта из списка альтернативных все же лучше использовать радиогруппу или комбобокс. Чекбоксы принято использовать для неальтернативных опций
Dr.Andrew (2008-08-27 04:51:00) [20]Спасибо