Форум: "Начинающим";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];
ВнизЯ рехнулся или Delphi? Найти похожие ветки
← →
IGray (2006-09-11 12:07) [0]Взгляните плииз на простейший код - почему он работает так, как будто 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.
← →
Dmitrij_K (2006-09-11 12:13) [1]
> должно "пикнуть", но не пищит!
Может пишалка не работает.
← →
Desdechado © (2006-09-11 12:14) [2]брякпойнт ставил?
← →
Dmitrij_K (2006-09-11 12:18) [3]
> Я рехнулся или Delphi?
в 99% случаях ты
← →
Сергей М. © (2006-09-11 12:19) [4]
> beep; // должно "пикнуть", но не пищит!
Windows.Beep(частота, длительность);
← →
Dell3r © (2006-09-11 12:19) [5]Попробуй так. :)
implementation
{$R *.dfm}
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
try
Write(1); // провоцируем исключение EInOutError (к примеру)
except
beep;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TreeView1.Items.AddChild(nil, "Node0");
TreeView1.Selected := TreeView1.Items[0];
end;
end.
← →
balepa © (2006-09-11 12:22) [6]Из под Дельфи запускал ?
← →
novill © (2006-09-11 12:31) [7]Действительно странно. Проверил на D6. Так и есть try except игнорит.
← →
Elen © (2006-09-11 12:31) [8]
> почему он работает
Потому чтоTreeView1.Selected := TreeView1.Items[0];
не вызывает обработкуTForm1.TreeView1Change
.
И вообще смотри [5] - это правильнее
← →
novill © (2006-09-11 12:36) [9]> > почему он работает
>
> Потому что TreeView1.Selected := TreeView1.Items[0];
> не вызывает обработку TForm1.TreeView1Change.
Вызывает, если текущий узел был другим
← →
Reindeer Moss Eater © (2006-09-11 12:39) [10]procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
{$I-}
Write(1);
if IOResult <> 0 then raise Exception.Create("не забываем читать факинмануал");
{$I+}
end;
← →
novill © (2006-09-11 12:41) [11]> [10] Reindeer Moss Eater © (11.09.06 12:39)
приprocedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
raise Exception.Create("что-то исключительное");
end;
ведет себя также ;-)
← →
Reindeer Moss Eater © (2006-09-11 12:43) [12]Как так же-то?
← →
novill © (2006-09-11 12:47) [13]как описано в [0] Не ловит исключение.
← →
Elen © (2006-09-11 12:48) [14]
> novill ©
так работает
procedure TForm1.Button1Click(Sender: TObject);
begin
TreeView1.Items.AddChild(nil, "Node0");
TreeView1.Selected := TreeView1.Items[0];
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
try
Write(1); // провоцируем исключение EInOutError (к примеру)
except
beep;
end; //
end;
← →
Reindeer Moss Eater © (2006-09-11 12:49) [15]Не ловит, потому что его там уже нет.
← →
IGray (2006-09-11 12:53) [16]
> Elen
> Потому что TreeView1.Selected := TreeView1.Items[0];
> не вызывает обработку TForm1.TreeView1Change.
если Selected=nil, то вызывает - 100%
> И вообще смотри [5] - это правильнее
врядли, так как в большинстве случаев правильнее пропустить исключение "наверх", но вопрос-то не в этом вообще, и не в том, как правильно "пискнуть" (это я для примера написал), а в том, что обработка исключений в Delphi вроде как сбоит 8-(
> Desdechado [2]
> брякпойнт ставил?
ставил - на beep вообще не попадает - сразу на дефолтный обработчик уходит :-(
> Dmitrij_K [3]
> > Я рехнулся или Delphi?
> в 99% случаях ты
знаю, и очень надеюсь, что и сейчас так, но пока всё говорит не в пользу Delphi..
← →
Reindeer Moss Eater © (2006-09-11 12:54) [17]>но пока всё говорит не в пользу Delphi..
А может все же справку открыть?
← →
novill © (2006-09-11 12:59) [18]> [14] Elen © (11.09.06 12:48)
понятно, что так исключение ловится, вопрос в другом.
> [15] Reindeer Moss Eater © (11.09.06 12:49)
Почему его там нет? Почему при появлении exception в процессе выполнения блока try ... except вызывает стандарный обрабочик исключения, а не описанный в блоке except?
Может, процитируешь справку по Дельфи, где такое поведение описано?
← →
Плохиш © (2006-09-11 13:02) [19]
> novill © (11.09.06 12:59) [18]
> Почему его там нет? Почему при появлении exception в процессе
> выполнения блока try ... except вызывает стандарный обрабочик
> исключения, а не описанный в блоке except?
А F7/F8 нажимать не пробовал? LMD
← →
novill © (2006-09-11 13:04) [20]> [19] Плохиш © (11.09.06 13:02)
а ты?
← →
han_malign © (2006-09-11 13:05) [21]
procedure TCustomTreeView.SetSelected(Value: TTreeNode);
begin
if Value <> nil then
Value.Selected := True
else
TreeView_SelectItem(Handle, nil);
end;
procedure TTreeNode.SetSelected(Value: Boolean);
begin
if not Deleting and (Handle <> 0) and (ItemId <> nil) then
if Value <> Selected then
begin
if Value then TreeView_SelectItem(Handle, ItemId)
else if Selected then TreeView_SelectItem(Handle, nil);
end
else if (TreeView.MultiSelect) and (TreeView.FSelections.Count > 1) then
TreeView.Select(Self, []);
end;
procedure TCustomTreeView.CNNotify(var Message: TWMNotify);
var
Node: TTreeNode;
MousePos: TPoint;
R: TRect;
DefaultDraw, PaintImages: Boolean;
TmpItem: TTVItem;
LogFont: TLogFont;
begin
with Message do
case NMHdr^.code of
........................................
TVN_SELCHANGEDA, TVN_SELCHANGEDW:
with PNMTreeView(NMHdr)^ do
if FChangeTimer.Interval > 0 then
with FChangeTimer do
begin
Enabled := False;
Tag := Integer(GetNodeFromItem(itemNew));
Enabled := True;
end
else
Change(GetNodeFromItem(itemNew));
........................................
end;
procedure TCustomTreeView.OnChangeTimer(Sender: TObject);
begin
FChangeTimer.Enabled := False;
Change(TTreeNode(FChangeTimer.Tag));
end;
даже если FChangeTimer.Interval = ChangeDelay = 0, исключение уходит в недра User32(?) в обработку очереди сообщений, а как оно(Delphi-йское) там обрабатывается я уже не знаю...
← →
IGray (2006-09-11 13:06) [22]
> Плохиш © (11.09.06 13:02) [19]
>
> > novill © (11.09.06 12:59) [18]
> > Почему его там нет? Почему при появлении exception в процессе
>
> > выполнения блока try ... except вызывает стандарный обрабочик
>
> > исключения, а не описанный в блоке except?
>
> А F7/F8 нажимать не пробовал? LMD
> Reindeer Moss Eater © (11.09.06 12:54) [17]
> Не ловит, потому что его там уже нет.
Если бы его там не было - дефолтный обработчик бы не вазывался.
> >но пока всё говорит не в пользу Delphi..
> А может все же справку открыть?
думаешь я 10 лет без справки по дельфе шарюсь? ;)
Если я что пропустил - скажи прямо плииз.
← →
IGray (2006-09-11 13:08) [23]сорри - криво процитировал..
← →
Плохиш © (2006-09-11 13:12) [24]
> IGray (11.09.06 13:06) [22]
> думаешь я 10 лет без справки по дельфе шарюсь? ;)
> Если я что пропустил - скажи прямо плииз.
То, что IDE-делфи останавливает выполнение программы при возникновении исключений, если это не отключено в настройках. После чего выполнение программы можно продолжить путём нажатия кнопок F7/F8/.. О чём в сообщении и пишется, но крютые прогеры, или читать не научились, или языков не знают, но вопить о глюках могут.
← →
Reindeer Moss Eater © (2006-09-11 13:14) [25]... use the $I+ directive to enable I/O checking ...
← →
han_malign © (2006-09-11 13:22) [26]O!!! Вот здесь оно и отлавливается...
procedure TWinControl.MainWndProc(var Message: TMessage);
begin
try
try
WindowProc(Message);
finally
FreeDeviceContexts;
FreeMemoryContexts;
end;
except
Application.HandleException(Self);
end;
end;
← →
Плохиш © (2006-09-11 13:28) [27]
> han_malign © (11.09.06 13:22) [26]
На строчке
> Write(1); // провоцируем исключение EInOutError (к примеру)
стек вызовов посмотри и всё поймёшь.
← →
IGray (2006-09-11 13:38) [28]
> Плохиш © (11.09.06 13:12) [24]
> То, что IDE-делфи останавливает выполнение программы при
> возникновении исключений, если это не отключено в настройках.
> После чего выполнение программы можно продолжить путём
> нажатия кнопок F7/F8/.. О чём в сообщении и пишется, но
> крютые прогеры, или читать не научились, или языков не знают,
> но вопить о глюках могут.
Я уже 10 лет это всё знаю, так что хватит наезжать - попробуй код сначала, если по делу сказать что хочешь, а хелпы не ты один читать умеешь.
> На строчке
> > Write(1); // провоцируем исключение EInOutError (к примеру)
> стек вызовов посмотри и всё поймёшь
Я посмотрел - и не понял на что ты намекаешь, может пора развеятьснять ореол загадочности?
> Reindeer Moss Eater © (11.09.06 13:14) [25]
> ... use the $I+ directive to enable I/O checking ...
Это я всё знаю..
Естественно I/O checking у меня включен (по умолчанию)
О чем собственно и свидетельствует то, что исключение возникает, и доходит до дефолтного обработчика.
---------------
Сейчай выяснил, что с обработчиком Edit1Change прикол тот же самый :-(
← →
han_malign © (2006-09-11 13:41) [29]
> стек вызовов посмотри и всё поймёшь
- одно но - не забудь включить Use debug DCUs
и попадешь в аккурат в han_malign © (11.09.06 13:22) [26]
← →
Плохиш © (2006-09-11 13:42) [30]
> IGray (11.09.06 13:38) [28]
> > На строчке
> > > Write(1); // провоцируем исключение EInOutError (к
> примеру)
> > стек вызовов посмотри и всё поймёшь
>
> Я посмотрел - и не понял на что ты намекаешь, может пора
> развеятьснять ореол загадочности?
Приводи сюда список вызовов и пойдём прямо по строчкам. Много времени не займёт, там их всего две.
← →
Плохиш © (2006-09-11 13:43) [31]
> han_malign © (11.09.06 13:41) [29]
>
> > стек вызовов посмотри и всё поймёшь
>
> - одно но - не забудь включить Use debug DCUs
Какое это отношение имеет к списку вызовов?
← →
IGray (2006-09-11 14:05) [32]
> Плохиш © [30]
> Приводи сюда список вызовов и пойдём прямо по строчкам.
TForm1.TreeView1Change(???,???)
Project1
> han_malign
Спасибо! Это что ж получается - дефолтный обработчик вызывается раньше моего?!!! Дурдом... И в каком же хелпе такая дикость описана....
А главное - как это обойти-то...
← →
Reindeer Moss Eater © (2006-09-11 14:12) [33]У тебя же в try/except обернут не тот код, который вызывает исключение.
← →
Elen © (2006-09-11 14:12) [34]
> IGray
А чем [14] не подходит? Поподробнее обрисуй ссуть...
← →
Reindeer Moss Eater © (2006-09-11 14:16) [35]Вокруг какой-то фигни раздули тему....
{$I+}
try
WriteLn;
except
ShowMessage("Вот оно пойманое исключение");
end;
← →
novill © (2006-09-11 14:16) [36]> [26] han_malign © (11.09.06 13:22)
Спасибо
>Плохиш
поищите достойную стену
← →
Плохиш © (2006-09-11 14:17) [37]
> 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];
← →
Плохиш © (2006-09-11 14:20) [38]
> novill © (11.09.06 14:16) [36]
> >Плохиш
> поищите достойную стену
Она находиться прямо за вами, можете уже разбегаться.
← →
vl_chel © (2006-09-11 14:22) [39]Если повторяюсь прошу извинить
Но если Вы вспомните то пока не закончилось выполнение одного обработчика события другой не начинает выполняться!!!
Поэтому зпись в поле Selected происходит после завершения обработчика TForm1.Button1Click поэтому вы не можете перехватить ситуацию исключения она возникает позднее
← →
Reindeer Moss Eater © (2006-09-11 14:28) [40]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:33) [41]но возможно я ошибся
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
← →
han_malign © (2006-09-11 14:46) [42]
> Спасибо! Это что ж получается - дефолтный обработчик вызывается
> раньше моего?!!! Дурдом... И в каком же хелпе такая дикость
> описана....
>
> А главное - как это обойти-то...
- если ты это обойдешь, то разрушишь очередь сообщений окна.
← →
han_malign © (2006-09-11 14:58) [43]
> 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 по этому пути не пошли...
← →
IGray (2006-09-11 15:24) [44]
> Elen © (11.09.06 14:12) [34]
> А чем [14] не подходит? Поподробнее обрисуй ссуть...
Суть в том, что крайне неудобно быть обязаным все исключения полностью подавлять внутри обработчиков событий. В большинстве случаев удобно и правильно "выпустить" исключение "на самый верх" к дефолтному обработчику, который я перекрываю, чтоб отправить письмо разработчику (мне) с инфой об ошибке.
А теперь выясняется, что вся стройная и логичная система летит к черту :-(
------------------
Я тут выполнил простецкий поиск по исходникам дельфийских модулей, и мне открылась страшная правда - во многих местах встречается код:
try
...
except
Application.HandleException(Self);
end;
Т.е. дефолтная обработка исключений ДЕЦЕНТРАЛИЗОВАНА!
Насколько я понимаю, отсюда вытекают следующие проблемы (как минимум):
1. Раз дефолтное подавление исключения может произойти до моего обработчика (размещенного "по месту"), то как мне узнать, что исключение ВООБЩЕ было и КАКОЕ?
2. Если я перекрываю дефолтный обработчик - как внутри него мне узнать, в каком КОНТЕКСТЕ он был вызван?
Подозреваю, что это еще и не все проблемы, так что мне всё-таки кажется борландовцы тут что-то перемутили...
← →
IGray (2006-09-11 15:29) [45]
> Reindeer Moss Eater
try
SendMessage(Handle,WM_MYMSG,0,0);
except
ShowMessage("С какой стати здесь чего-то ждать?");
end;
Если бы вместо SendMessage ты использовал PostMessage я бы ничего и не ждал, но SendMessge полностью отрабатывается там где написано, т.е. до except, поэтому моё ожидание считаю логичным...
← →
Наиль © (2006-09-11 15:35) [46]
> Если бы вместо SendMessage ты использовал PostMessage я
> бы ничего и не ждал, но SendMessge полностью отрабатывается
> там где написано, т.е. до except, поэтому моё ожидание считаю
> логичным...
SendMessage может быть и не твоим.
Неужели вражеская программа должна подрываться на твоих ошибках, при оращении к контролам твоей программы?
← →
Reindeer Moss Eater © (2006-09-11 15:42) [47]А что это меняет? Ничего.
Кодовый поток дошел до синхронного вызова. Сообщение отправлено.
Какой код после этого и в каком процессе при этом запускается - delphi по барабану.
поэтому моё ожидание считаю логичным...
Вот допустим есть приложение (чьё-то не мое и не твое) с окном. И у этого окна есть обработчик сообщения. И в нем выполняется потенциально опасный код могущий генерировать исключения.
По твоей логике, если написать сбоку еще одно приложение, и из него отправить сообщение в то первое приложение и обернуть вызов в обработчик, то это второе приложение должно чудесным образом загасить исключения в первом приложении.
← →
Reindeer Moss Eater © (2006-09-11 15:45) [48]А если сообщение посылается из прилады сделанной с помощью компилятора, не имеющего представления вообще об обработке исключений?
← →
Elen © (2006-09-11 15:51) [49]
> дефолтная обработка исключений ДЕЦЕНТРАЛИЗОВАНА!
Для таких задач Борланд придумал TException. Рули им.
← →
IGray (2006-09-11 16:04) [50]
> По твоей логике, если написать сбоку еще одно приложение,
> и из него отправить сообщение в то первое приложение и
> обернуть вызов в обработчик, то это второе приложение должно
> чудесным образом загасить исключения в первом приложении.
По моей логике второе приложение может загасить те исключения возникшие в первом, которые первое решило не обрабатывать. Возможно первое сообщает второму через исключение, что второе передало первому недопустимые данные...
> А если сообщение посылается из прилады сделанной с помощью
> компилятора, не имеющего представления вообще об обработке
> исключений?
А если сообщение посылают инопланетяне?
;-)
← →
Reindeer Moss Eater © (2006-09-11 16:14) [51]Ну в общем я вижу, что ты все же понял
← →
Наиль © (2006-09-11 16:16) [52]
> Возможно первое сообщает второму через исключение
главное слово - возможно.
Нельзя опирается на то, что есть вероятность.
Поэтому Борланд оставляет исключения которые возможно пришли из вне, себе. Программист должен быть уверен, что ошибки в других программах не повлияют на его (правильно написанную) программу.
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.018 c