Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.01.15;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.004 c
9-1188822716
ПисательПлоскихИгр
2007-09-03 16:31
2012.01.15
Zero3D


3-1269856885
Чайник
2010-03-29 14:01
2012.01.15
TClientDataSet - перевод в режим редактирования.


1-1279183953
TKN
2010-07-15 12:52
2012.01.15
QuickReport - вывести в файл


15-1317550613
Loginov Dmitry
2011-10-02 14:16
2012.01.15
Indy - работа с электронной почтой


15-1316896202
Юрий
2011-09-25 00:30
2012.01.15
С днем рождения ! 25 сентября 2011 воскресенье





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский