| 
| 
 | Вопрос # 3 674/ вопрос решён / | 
 |  Здравствуйте, эксперты!Использую в секции initialization процедуру Assert. Как сделать, чтобы прежде чем сдохнуть приложение выдало моё сообщение, а не "Runtime error xx at xxxxxxxx".
 
|  |   Вопрос задал: DNK (статус: Студент)Вопрос отправлен: 22 января 2010, 15:15
 Состояние вопроса: решён, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, Ершов Денис!если хочется свое сообщение, то просто надо его написать, где то так
 Assert(Result = 0, 'Ошибка в алгоритме');
 Но если хочется ещё и номер строки в файле узнать, и файл лога все это дело записать, то тогда надо регистрировать свой обработчик. подробности и примеры тут http://www.delphimaster.ru/articles/errors/index.html
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 22 января 2010, 15:43
 Оценка за ответ: 5
 Комментарий к оценке: Проблема не в незнании процедуры Assert, а в том, что в секции initialization некому обработать вызванное им исключение. В чем-то помогла статья, воспользовался заменой указателя AssertErrorProc. Найти бы такую же для переопределения процедур обработки исключений. |  
 Мини-форум вопросаВсего сообщений: 13; последнее сообщение — 29 января 2010, 15:10; участников в обсуждении: 5. 
|   | min@y™ (статус: Доктор наук), 23 января 2010, 09:52 [#1]:Ты бы код показал, а то телепатор отключили за неуплату. Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | vlsavkin (статус: 2-ой класс), 23 января 2010, 12:23 [#2]:Возможно Вам нужна не процедура Assert, а просто обработка исключений? Сравните: procedure TForm1.Button1Click(Sender: TObject);
 var a:Single;
 i:Integer;
 begin
 try
 i:=0;
 a:=5/i;
 except
 ShowMessage('Ошибка деления');
 end;
 end;
 и
 procedure TForm1.Button1Click(Sender: TObject);
 var a:Single;
 i:Integer;
 begin
 i:=0;
 a:=5/i;
 end;
 
 Еще в таком случае удобно снять галочку Stop On Delphi Exceptions в Debugger Option, вкладка Language Exceptions, чтобы видеть сообщения об ошибках, как будет видеть их пользователь, без приостанавливания программы. Для отладки же конечно нужно оставлять ее включенной.
 |  
|   | DNK (статус: Студент), 25 января 2010, 11:31 [#3]:2min@y™: В программе порядка 66000 строк, плюс ветви. Вроде все понятно и без кода. Есть секции инициализации в некоторох модулях и нужно централизованно отловить в них исключения (пока модулей только 10 и процедуры них генерируют только EAssertionFailed). Схемотично это выглядит так: 1)Основной модуль
 
 unit RegeisterUnit;
 
intreface
 
function RegisterFormClass(code: byte; clazz: FormClass);
 
implementation
 
function RegisterFormClass;
begin
  ...
  Assert(...);
end;
 
end.2)Переферия 
 unit TestUnit;
 
type 
  TTetsForm = class (Form) 
 
...
 
initialization
  RegisterFormClass(TestCode, TTestForm);
 
end. "Digital Networked Knight" |  
|   | Вадим К (статус: Академик), 25 января 2010, 11:53 [#4]:Я думаю, в данном случае оптимально будет отказаться от секции initialization. Почему? - компилятор не гарантирует, в каком порядке он будет вызвать эти секции
 - много переменных на данный момент находятся в неопределенном состоянии.
 
 Лучше в основном коде сделать вызов, который пробежится и зарегистрирует всё.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | DNK (статус: Студент), 26 января 2010, 09:54 [#5]:Порядок вызова не важен, все регистрируемые модули равнозначны. Я как раз и пытаюсь таким способом избавиться от "вызовов в основном коде, которые по чему-то там пробегаются и чего-то проверяют", ибо замучился со слиянием веток в SVN. "Digital Networked Knight" |  
|   | Вадим К (статус: Академик), 26 января 2010, 11:19 [#6]:Слияние веток не причина уродовать код. В целом делается так - пишется инстукция по модулям, как кто кого и когда вызывает, несоблюдение - выговор.
 - каждый модуль предоставляет функцию/процедуру/метод установленного образца, которую он регистрирует в массиве функций (это в принципе уже есть в вышеприведенном коде). Но вот только за одним отличием - только регистрация и ничего больше. никаких проверок/чтения конфигов. А вот уже основной код берет массив функций и по порядку выполняет. Именно так в делфи сделана регистрация компонентов.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | DNK (статус: Студент), 26 января 2010, 15:54 [#7]:А как получить этот массив функций? "Digital Networked Knight" |  
|   | Вадим К (статус: Академик), 26 января 2010, 16:26 [#8]:посмотрите как в делфи устроено RegisterComponent Галочка "подтверждения прочтения" - вселенское зло. |  
|   | DNK (статус: Студент), 26 января 2010, 17:02 [#9]:А что это? Не нахожу такого идентификатора. "Digital Networked Knight" |  
|   | Вадим К (статус: Академик), 26 января 2010, 17:13 [#10]:маленькая поправочка RegisterComponents Находиться в модуле Classes.pas
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Тамара (статус: Посетитель), 26 января 2010, 20:15 [#11]:А если запустить через exeшник? |  
|   | DNK (статус: Студент), 27 января 2010, 08:24 [#12]:2Вадим К: То-то же. Не вижу, чем эта процедура мне поможет. Она просто проверяет, существует ли точка входа регистрации и запускает её. Список компонентов для процедуры задается программистом ручками, от чего я и пытаюсь избавиться. "Digital Networked Knight" |  
|   | DNK (статус: Студент), 29 января 2010, 15:10 [#13]:В конечном итоге от assert отказался. Написал свою процедуру. procedure Fatality(assert: boolean; Msg: string);
begin
  if not assert then begin
    // Выводим сообщение
    MessageBox(0, PChar(Msg), 'Фатальная ошибка', MB_OK + MB_ICONSTOP);
    // Выходим из программы
    ExitProcess(1);
  end;
end;Стараюсь по возможности избегать исключений. Там где нет возможности:try
...
except
  on E: Exception do
    Fatality(false, E.message);
end;"Digital Networked Knight" |  13 мая 2011, 09:38: Статус вопроса изменён на решённый (изменил автор вопроса — DNK): Всё отлично работает. Испытано временем. Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |