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

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

Я рехнулся или Delphi?


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

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 обернут не тот код, который вызывает исключение.


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

Наверх

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