Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.014 c
10-1124007634
Андрей В.
2005-08-14 12:20
2006.10.01
Отключенные картинки в TWebBrowser


15-1158155534
Vlad Oshin
2006-09-13 17:52
2006.10.01
Мелочи жизни. мини-рассказ


15-1158159660
vain
2006-09-13 19:01
2006.10.01
TTB


15-1157982695
Cyrax
2006-09-11 17:51
2006.10.01
Тонкости Delphi


2-1157807035
DelphiN#1
2006-09-09 17:03
2006.10.01
СкринШоты





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский