![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Я рехнулся или Delphi?
IGray © (2006-09-11 12:07:00)Взгляните плииз на простейший код - почему он работает так, как будто try..except там вообще нет?!
В чем дело - есть гипотезы?
Заранее спасибо!
-----------------------------------------
implementation
{$R *.dfm}
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
Write(1); // провоцируем исключение EInOutError (к примеру)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TreeView1.Items.AddChild(nil, 'Node0');
try
TreeView1.Selected := TreeView1.Items[0];
except
beep; // должно "пикнуть", но не пищит!
end; // исключение вообще не перехватывается!
end;
end.
Наиль (2006-09-11 16:16:00) [1]
> Возможно первое сообщает второму через исключение
главное слово - возможно.
Нельзя опирается на то, что есть вероятность.
Поэтому Борланд оставляет исключения которые возможно пришли из вне, себе. Программист должен быть уверен, что ошибки в других программах не повлияют на его (правильно написанную) программу.
Reindeer Moss Eater (2006-09-11 16:14:00) [2]Ну в общем я вижу, что ты все же понял
IGray (2006-09-11 16:04:00) [3]
> По твоей логике, если написать сбоку еще одно приложение,
> и из него отправить сообщение в то первое приложение и
> обернуть вызов в обработчик, то это второе приложение должно
> чудесным образом загасить исключения в первом приложении.
По моей логике второе приложение можетзагасить те исключения возникшие в первом, которые первое решило не обрабатывать. Возможно первое сообщает второму через исключение, что второе передало первому недопустимые данные...
> А если сообщение посылается из прилады сделанной с помощью
> компилятора, не имеющего представления вообще об обработке
> исключений?
А если сообщение посылают инопланетяне?
;-)
Elen (2006-09-11 15:51:00) [4]
> дефолтная обработка исключений ДЕЦЕНТРАЛИЗОВАНА!
Для таких задач Борланд придумал TException. Рули им.
Reindeer Moss Eater (2006-09-11 15:45:00) [5]А если сообщение посылается из прилады сделанной с помощью компилятора, не имеющего представления вообще об обработке исключений?
Reindeer Moss Eater (2006-09-11 15:42:00) [6]А что это меняет? Ничего.
Кодовый поток дошел до синхронного вызова. Сообщение отправлено.
Какой код после этого и в каком процессе при этом запускается - delphi по барабану.
поэтому моё ожидание считаю логичным...
Вот допустим есть приложение (чьё-то не мое и не твое) с окном. И у этого окна есть обработчик сообщения. И в нем выполняется потенциально опасный код могущий генерировать исключения.
По твоей логике, если написать сбоку еще одно приложение, и из него отправить сообщение в то первое приложение и обернуть вызов в обработчик, то это второе приложение должно чудесным образом загасить исключения в первом приложении.
Наиль (2006-09-11 15:35:00) [7]
> Если бы вместо SendMessage ты использовал PostMessage я
> бы ничего и не ждал, но SendMessge полностью отрабатывается
> там где написано, т.е. до except, поэтому моё ожидание считаю
> логичным...
SendMessage может быть и не твоим.
Неужели вражеская программа должна подрываться на твоих ошибках, при оращении к контролам твоей программы?
IGray (2006-09-11 15:29:00) [8]
> Reindeer Moss Eater
try
SendMessage(Handle,WM_MYMSG,0,0);
except
ShowMessage('С какой стати здесь чего-то ждать?');
end;
Если бы вместо SendMessageты использовал PostMessageя бы ничего и не ждал, но SendMessge полностью отрабатывается там где написано, т.е. до except, поэтому моё ожидание считаю логичным...
IGray (2006-09-11 15:24:00) [9]
> Elen© (11.09.06 14:12) [34]
> А чем [14] не подходит? Поподробнее обрисуй ссуть...
Суть в том, что крайне неудобно быть обязаным все исключения полностью подавлять внутри обработчиков событий. В большинстве случаев удобно и правильно "выпустить" исключение "на самый верх" к дефолтному обработчику, который я перекрываю, чтоб отправить письмо разработчику (мне) с инфой об ошибке.
А теперь выясняется, что вся стройная и логичная система летит к черту :-(
------------------
Я тут выполнил простецкий поиск по исходникам дельфийских модулей, и мне открылась страшная правда - во многихместах встречается код:
try
...
except
Application.HandleException(Self);
end;
Т.е. дефолтная обработка исключений ДЕЦЕНТРАЛИЗОВАНА!
Насколько я понимаю, отсюда вытекают следующие проблемы (как минимум):
1. Раз дефолтное подавление исключения может произойти до моего обработчика (размещенного "по месту"), то как мне узнать, что исключение ВООБЩЕ было и КАКОЕ?
2. Если я перекрываю дефолтный обработчик - как внутри него мне узнать, в каком КОНТЕКСТЕ он был вызван?
Подозреваю, что это еще и не все проблемы, так что мне всё-таки кажется борландовцы тут что-то перемутили...
han_malign (2006-09-11 14:58:00) [10]
> han_malign © (11.09.06 14:46) [42]
можешь убедиться сам:
procedure TForm1._exc(Sender: TObject; E: Exception);
begin
raise E.ClassType.Create;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException:= _exc;
end;
Единственный приемлемый вариант востановления исключения VCL, возникающего в очереди сообщения, это запомнить его в глобальной переменной, "перекрыть" SendMessage, в котором, после отработки генерить "запомненное" исключение. Но это приведет к значительным накладным расходам, ловить будет не все(отложенные нотификации не пройдут),так что понятно почему разработчики Borland по этому пути не пошли...
han_malign (2006-09-11 14:46:00) [11]
> Спасибо! Это что ж получается - дефолтный обработчик вызывается
> раньше моего?!!! Дурдом... И в каком же хелпе такая дикость
> описана....
>
> А главное - как это обойти-то...
- если ты это обойдешь, то разрушишь очередь сообщений окна.
vl_chel (2006-09-11 14:33:00) [12]но возможно я ошибся
procedure TForm1.Edit1Change(Sender: TObject);
begin
ShowMessage('12');
raise Exception.Create('Error');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
Edit1.Text := '33445';
ShowMessage('11');
except
ShowMessage('M Error');
end;
end;
Переход на обработку исключения вообще не происходит????
пишет:
12
Error
11
Хотя по логике код обработчика должен быть снят с выполнения и 11 выводиться не должно ??
В случае такого кода все работает вполне корректно
try
Edit1.Text := '33445';
raise Exception.Create('Error');
ShowMessage('11');
except
ShowMessage('M Error');
end;
12
Error
M Error
Возможно это связано со спецификой внутренней обработки исключений в VCL
Reindeer Moss Eater (2006-09-11 14:28:00) [13]procedure TForm1.OnMyMsg(var Msg: TMessage);
begin
Writeln;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
{$I+}
try
Writeln;
except
ShowMessage('Оппа!');
end;
try
SendMessage(Handle,WM_MYMSG,0,0);
except
ShowMessage('С какой стати здесь чего-то ждать?');
end;
end;
vl_chel (2006-09-11 14:22:00) [14]Если повторяюсь прошу извинить
Но если Вы вспомните то пока не закончилось выполнение одного обработчика события другой не начинает выполняться!!!
Поэтому зпись в поле Selected происходит после завершения обработчика TForm1.Button1Click поэтому вы не можете перехватить ситуацию исключения она возникает позднее
Плохиш (2006-09-11 14:20:00) [15]
> novill © (11.09.06 14:16) [36]
> >Плохиш
> поищите достойную стену
Она находиться прямо за вами, можете уже разбегаться.
Плохиш (2006-09-11 14:17:00) [16]
> IGray (11.09.06 14:05) [32]
> TForm1.TreeView1Change(???,???)
> Project1
А теперь покажи, где здесь находиться TForm1.Button1Click.
По строчкам
Исключение произошло в TForm1.TreeView1Change и не было там подавлено, соответственно оно перерешло в цикл обработки сообщенийосновной программы, где и было обработано штатным образом. Это является документированной работой системы вындовс. Для изменения состояния чего-либо, этому что-либо посылается сообщение, которое будет когда-то обработано в цикле выборки сообщений.
> han_malign © (11.09.06 13:41) [29]
> - одно но - не забудь включить Use debug DCUs
Идти пошагово надо от строки
> TreeView1.Selected := TreeView1.Items[0];
novill (2006-09-11 14:16:00) [17]> [26] han_malign © (11.09.06 13:22)
Спасибо
>Плохиш
поищите достойную стену
Reindeer Moss Eater (2006-09-11 14:16:00) [18]Вокруг какой-то фигни раздули тему....
{$I+}
try
WriteLn;
except
ShowMessage('Вот оно пойманое исключение');
end;
Elen (2006-09-11 14:12:00) [19]
> IGray
А чем [14] не подходит? Поподробнее обрисуй ссуть...
Reindeer Moss Eater (2006-09-11 14:12:00) [20]У тебя же в try/except обернут не тот код, который вызывает исключение.