Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.01.15;
Скачать: CL | DM;

Вниз

Обработка ошибок в открывающейся форме   Найти похожие ветки 

 
Laguna ©   (2011-10-05 10:28) [0]

Из главной формы открывается другая, в которой открываются таблицы. Во время открытия могут возникнуть ошибки(отсутствует файл, отсутствует индекс и т.д). Как правильно не допустить конечное открытие формы, если на этапе onCreate возникли ошибки. Из главной формы вход оформлен вот так :

 Screen.Cursor := crHourGlass;
 M_Frm := TM_Frm.Create(Application);
 M_Frm.Lab1.Caption := "Выполняется подготовка, ожидайте...";
 M_Frm.Show;
 M_Frm.Update;
 S_Frm := TS_Frm.Create(Application);
 S_Frm.ShowModal;
 M_Frm.Hide;
 M_Frm.Free;
 Screen.Cursor := crDefault;
 S_Frm.CLose;
 S_Frm.Free;



procedure TS_Frm.FormCreate(Sender: TObject);
Var
 ErrorString : String;
begin
 try
   DM1.T1Tbl.Open;
   DM1.T2Tbl.Open;
   DM1.T3Tbl.Open;
   DM1.T4Tbl.Open;
   DM1.T5Tbl.Open;
 except
   on E: EDatabaseError do
     application.messagebox( pchar(E.message), "Native Database Error", 0 );
 end;
end;


 
И. Павел ©   (2011-10-05 10:36) [1]

Можно перехватывать ошибки не в FormCreate а в вызывающей функции, т.е.:

try
M_Frm := TM_Frm.Create(Application);
except
  ...
  Exit;
end;
S_Frm.ShowModal;


 
Laguna ©   (2011-10-05 10:46) [2]

Этот вариант я просматривал. Уточнюсь дополнительно. Если произошла ошибка в момент создания формы в блоке try, то успела ли выделися для нее память и нужно ли в Except добавить S_Frm.Free ?


 
Ega23 ©   (2011-10-05 10:55) [3]

Делай это не на OnCreate, а заведи отдельный public-метод. Его и дёргай:

with TSomeForm.Create(Application) do
 try
   try
     InitSomeForm;  <-- Вот в этом методе и реализуешь всю загрузку из БД или чё там...
   except on E: Exception do
     ShowMessage("Epic Fail!" + sLineBreak + E.Message);
   end;
 finally
   Free;
 end;


 
Ega23 ©   (2011-10-05 10:55) [4]

Забыл:

with TSomeForm.Create(Application) do
try
  try
    InitSomeForm;  <-- Вот в этом методе и реализуешь всю загрузку из БД или чё там...
    ShowModal;
  except on E: Exception do
    ShowMessage("Epic Fail!" + sLineBreak + E.Message);
  end;
finally
  Free;
end;


 
И. Павел ©   (2011-10-05 10:56) [5]

> [2] Laguna ©   (05.10.11 10:46)

free делать не нужно. При возникновении исключения в конструкторе, все очистится автоматически.


 
Ega23 ©   (2011-10-05 10:59) [6]


> все очистится автоматически.


вызовется destructor


 
Laguna ©   (2011-10-05 11:05) [7]

Брр.. не совсем понял зачем дополнительный метод? Что это даст? TsomeForm в данном случае , применительно к моему вопросу какая форма выступает? Здесь главное не так ошибку описать, как не допустить загрузки формы в случае ошибки.


 
Ega23 ©   (2011-10-05 11:13) [8]


> как не допустить загрузки формы в случае ошибки.

Я уже ответил. Вынеси весь код из TSomeForm.OnCreate в TSomeForm.InitSomeForm;


 
Laguna ©   (2011-10-05 11:30) [9]

Дело в том, что из [1] видно , что из главной формы у меня так же запускается информационное окно (M_Frm := TM_Frm.Create(Application);) Для него же тоже нужно отлавливать закрытие и высвобождение памяти если произошла ошибка. А этот код я так понял выполняется во второй форме

with TSomeForm.Create(Application) do
try
  try
    InitSomeForm;  <-- Вот в этом методе и реализуешь всю загрузку из БД или чё там...
    ShowModal;
  except on E: Exception do
    ShowMessage("Epic Fail!" + sLineBreak + E.Message);
  end;
finally
  Free;
end;


 
Ega23 ©   (2011-10-05 11:36) [10]


> Дело в том, что из [1] видно , что из главной формы у меня
> так же запускается информационное окно (M_Frm := TM_Frm.
> Create(Application);)


Если честно, то:
1. Код вообще непонятен. Что такое TM_Frm и TS_Frm - тебе может быть и понятно, но другим нет.
2. Непонятна вообще вся архитектура приложения.
3. Непонятна суть вопроса.

Я вопрос понял так: есть некая модальная форма. При её создании делается много вещей, где может возникнуть исключение, как это лучше обработать?


 
Anatoly Podgoretsky ©   (2011-10-05 11:50) [11]


>  M_Frm := TM_Frm.Create(Application);

на вопрос отвечает этот код, как уже указали некоторые

M_Frm := TM_Frm.Create(Application);
try


 
_Юрий   (2011-10-05 11:51) [12]

Проще поступить не так.
Если выполнить потенциально опасный код не в OnCreate, а непосредственно в переопределенном конструкторе, желаемое поведение получится автоматически


 
Ega23 ©   (2011-10-05 11:56) [13]


> Если выполнить потенциально опасный код не в OnCreate, а
> непосредственно в переопределенном конструкторе


Что-то я не понял. Приведи пример.


 
Laguna ©   (2011-10-05 12:06) [14]


> Если честно, то:1. Код вообще непонятен. Что такое TM_Frm
> и TS_Frm - тебе может быть и понятно, но другим нет.2. Непонятна
> вообще вся архитектура приложения.3. Непонятна суть вопроса.

S_Frm и M_Frm названия двух форм. В [1] разве не видно как они создаются?

M_Frm := TM_Frm.Create(Application);
S_Frm := TS_Frm.Create(Application);


> Я вопрос понял так: есть некая модальная форма. При её создании
> делается много вещей, где может возникнуть исключение, как
> это лучше обработать?


В принципе так. Есть главная форма. В ней создается модальная форма S_Frm , в которой в свою очередь открываются таблицы.... Ну опять [1] переписывать?


 
Ega23 ©   (2011-10-05 12:09) [15]


>  Есть главная форма. В ней создается модальная форма S_Frm
> , в которой в свою очередь открываются таблицы.... Ну опять
> [1] переписывать?


Тогда ответ уже дан.


 
_Юрий   (2011-10-05 12:31) [16]


> Что-то я не понял. Приведи пример.


type
 TS_Frm = class(TForm)
 public
   constructor Create(AOwner: TComponent); override;
 end;

constructor TS_Frm.Create(AOwner: TComponent);
begin
 inherited;
 А тут код открытия таблиц и прочее
end;

При возникновении исключения форма автоматически разрушится, и на экране ничего  показано не будет.
В отличие от OnCreate, которое вызывается не из тела конструктора, а из AfterConstruction


 
Ega23 ©   (2011-10-05 12:47) [17]


> В отличие от OnCreate, которое вызывается не из тела конструктора,
>  а из AfterConstruction


constructor TCustomForm.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
{$IF DEFINED(CLR)}
 GlobalNameSpace.AcquireWriterLock(MaxInt);
{$ELSE}
 GlobalNameSpace.BeginWrite;
{$IFEND}
 try
   FCreatingMainForm := Application.FCreatingMainForm;
   if FCreatingMainForm then
     Application.FCreatingMainForm := False;

   InitializeNewForm;
   if (ClassType <> TForm) and not (csDesigning in ComponentState) then
   begin
     Include(FFormState, fsCreating);
     try
       if not InitInheritedComponent(Self, TForm) then
         raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
     finally
       Exclude(FFormState, fsCreating);
     end;
{$IF NOT DEFINED(CLR)}
     if OldCreateOrder then
{$IFEND}
       DoCreate;
   end;
 finally
{$IF DEFINED(CLR)}
   GlobalNameSpace.ReleaseWriterLock;
{$ELSE}
   GlobalNameSpace.EndWrite;
{$IFEND}
 end;
end;


 
_Юрий   (2011-10-05 14:04) [18]


> Ega23 ©   (05.10.11 12:47) [17]


В зависимости от значения OldCreateOrder - или в конструкторе, или в AfterConstruction, по умолчанию - второе.
Можно конечно выставить это свойство в true. Но на мой взгляд, ни к чему завязываться на состояние без необходимости.


 
Ega23 ©   (2011-10-05 14:14) [19]


> или в AfterConstruction, по умолчанию - второе.


Зависит от того, до inherited или после.
Только мне всё равно непонятно преимущество вызова исключения в конструкторе. Не, я в принципе понимаю, что можно, TFileStream и всё такое. Но преимуществ не вижу.

З.Ы. Что-то я туплю уже...


 
Игорь Шевченко ©   (2011-10-05 15:30) [20]


> При возникновении исключения форма автоматически разрушится,
>  и на экране ничего  показано не будет.


будет


 
OW ©   (2011-10-05 15:36) [21]

S_Frm := CreateForm_TSFrm;
if S_Frm =|<> nil then

function CreateForm_TSFrm: TS_Frm;
result := nil;
try
  DM1.T1Tbl.Open;
  DM1.T2Tbl.Open;
  DM1.T3Tbl.Open;
  DM1.T4Tbl.Open;
  DM1.T5Tbl.Open;
  result := TS_Frm.Create(Application);
except
  on E: EDatabaseError do
    application.messagebox( pchar(E.message), "Native Database Error", 0 );
end;


 
_Юрий   (2011-10-05 15:43) [22]


> Ega23 ©   (05.10.11 14:14) [19]



procedure TCustomForm.AfterConstruction;
begin
 if not OldCreateOrder then DoCreate;



> Игорь Шевченко ©   (05.10.11 15:30) [20]


И что же будет показано?


 
_Юрий   (2011-10-05 15:46) [23]


> Ega23 ©   (05.10.11 14:14) [19]


> Только мне всё равно непонятно преимущество вызова исключения
> в конструкторе.


Оно в том, что не нужно совершать дополнительных плясок с try-except или с введением дополнительных методов инициализации


 
Игорь Шевченко ©   (2011-10-05 17:10) [24]


> И что же будет показано?


форма


 
Ega23 ©   (2011-10-05 17:16) [25]


> Игорь Шевченко ©   (05.10.11 17:10) [24]
>
> > И что же будет показано?
> форма


Если в AfterConstruction исключение поднять, то не будет.
Пруф:

unit Unit23;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm23 = class(TForm)
   Memo1: TMemo;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   procedure AfterConstruction; override;

 end;

var
 Form23: TForm23;

implementation

{$R *.dfm}

procedure TForm23.AfterConstruction;
begin
 Memo1.Lines.Add("TForm23.AfterConstruction; before inherited");
 inherited;
 raise Exception.Create("Error Message");
 Memo1.Lines.Add("TForm23.AfterConstruction; after inherited");
end;

procedure TForm23.FormCreate(Sender: TObject);
begin
 Memo1.Lines.Add("TForm23.FormCreate(Sender: TObject);");
//  raise Exception.Create("Error Message");
end;

end.


Опробовано с обоими вариантами OldCreateOrder


 
Ega23 ©   (2011-10-05 17:18) [26]

Если поднять в OnCreate - таки будет, также с обоими вариантами


 
MsGuns ©   (2011-10-05 17:26) [27]

А если попробовать выкопать морковку без трактора, комбайна, эскаватора, звена колхозниц и роты пулеметчиков - просто голыми руками:

procedure TForm1.OnActivate(Sender: TObject);
begin
 if (Tag>0) then exit;
 try
    ... // Открытие всех нужных таблиц
    Tag := 1;
 except
    ShowMessage("Ошибка открытия") ;
 end;
end;


 
Ega23 ©   (2011-10-05 17:33) [28]


> .OnActivate


Вот это как раз не следует. Нафига показывать то, что уже не прошло валидацию?


 
MsGuns ©   (2011-10-05 17:36) [29]

Тогда формочку-сплитер.


 
OW ©   (2011-10-05 17:39) [30]

ну а чем плохо

все открыть, если все нормально, то и создать форму
если нет - все закрыть "взад" и поругаться


 
MsGuns ©   (2011-10-05 17:46) [31]

Вообще-то положено какбы предварительно логиниться к базе, а без формы это сделать затруднительно. И если возникает ошибка, то сообщать о ее характере, предлагая пользователю попробовать еще раз (например после выяснения у админа новых парметров соединения). Как собсна сделаны все субэдэшные сервисы.
Однако тут как всегда дружно и вдохновенно изобретают велосипед


 
Ega23 ©   (2011-10-05 17:54) [32]


>  а без формы это сделать затруднительно


Для таких целей существует DataModule


 
MsGuns ©   (2011-10-05 18:03) [33]

Датамодуль нужен совсем для других целей


 
_Юрий   (2011-10-05 18:37) [34]


> Игорь Шевченко ©   (05.10.11 17:10) [24]


> форма


Не сразу заметил, что автор ловит исключение. Речь идет разумеется о случае, когда исключение не отлавливается.

Автор - не лови исключение! И никакой формы тогда показано не будет.


> Ega23 ©   (05.10.11 17:16) [25]



> Если в AfterConstruction исключение поднять, то не будет.

Если исключение поднялось  где угодно перед вызовом Show(Modal), то разумеется не будет, просто потому что мы не попадаем на Show(Modal)


 
Игорь Шевченко ©   (2011-10-05 19:57) [35]

_Юрий   (05.10.11 18:37) [34]

автор спрашивает:


> Как правильно не допустить конечное открытие формы, если
> на этапе onCreate возникли ошибки


Между прочим, это один из моих вопросов кандидатам на собеседовании :)


 
Ega23 ©   (2011-10-05 20:08) [36]


> Между прочим, это один из моих вопросов кандидатам на собеседовании
> :)


PostMessage WM_CLOSE


 
Ega23 ©   (2011-10-05 20:09) [37]


> MsGuns ©   (05.10.11 18:03) [33]
>
> Датамодуль нужен совсем для других целей


Ну давай уже тогда, описывай, для чего он нужен.


 
DiamondShark ©   (2011-10-05 20:12) [38]


> Между прочим, это один из моих вопросов кандидатам на собеседовании :)

Если задумался, и собрался отвечать -- гнать поганой метлой.
Ответивший на этот вопрос будет хранить данные в TreeView и всю бизнес-логику писать внутри Button1Click. Нафиг никому не нужен такой кандидат.


 
DiamondShark ©   (2011-10-05 20:15) [39]


> OW ©   (05.10.11 17:39) [30]
> ну а чем плоховсе открыть, если все нормально, то и создать
> формуесли нет - все закрыть "взад" и поругаться

Это не по дельфийски.


 
Игорь Шевченко ©   (2011-10-05 20:16) [40]


> Ответивший на этот вопрос будет хранить данные в TreeView
> и всю бизнес-логику писать внутри Button1Click


До сих пор указанного соответствия не наблюдалось



Страницы: 1 2 вся ветка

Текущий архив: 2012.01.15;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.009 c
15-1317153552
xayam
2011-09-27 23:59
2012.01.15
ExeClient = WebKit + HTML + CSS + JavaScript


2-1317911115
vegarulez
2011-10-06 18:25
2012.01.15
Звук при нажатии Enter


15-1317155402
Юрий
2011-09-28 00:30
2012.01.15
С днем рождения ! 28 сентября 2011 среда


15-1315577144
bss
2011-09-09 18:05
2012.01.15
TOleContainer, Excel - недоступно меню "Файл" и пр.


9-1175164239
crytogen
2007-03-29 14:30
2012.01.15
нарисовать трубу в OpenGL по точкам