![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обработка ошибок в открывающейся форме [D7, XP]
Laguna © (2011-10-05 10:28:00)Из главной формы открывается другая, в которой открываются таблицы. Во время открытия могут возникнуть ошибки(отсутствует файл, отсутствует индекс и т.д). Как правильно не допустить конечное открытие формы, если на этапе 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;
Ega23 (2011-10-05 20:08:00) [41]
> Между прочим, это один из моих вопросов кандидатам на собеседовании
> :)
PostMessage WM_CLOSE
Игорь Шевченко (2011-10-05 19:57:00) [42]_Юрий (05.10.11 18:37) [34]
автор спрашивает:
> Как правильно не допустить конечное открытие формы, если
> на этапе onCreate возникли ошибки
Между прочим, это один из моих вопросов кандидатам на собеседовании :)
_Юрий (2011-10-05 18:37:00) [43]
> Игорь Шевченко © (05.10.11 17:10) [24]
> форма
Не сразу заметил, что автор ловит исключение. Речь идет разумеется о случае, когда исключение не отлавливается.
Автор - не лови исключение! И никакой формы тогда показано не будет.
> Ega23 © (05.10.11 17:16) [25]
> Если в AfterConstruction исключение поднять, то не будет.
Если исключение поднялось где угодно перед вызовом Show(Modal), то разумеется не будет, просто потому что мы не попадаем на Show(Modal)
MsGuns (2011-10-05 18:03:00) [44]Датамодуль нужен совсем для других целей
Ega23 (2011-10-05 17:54:00) [45]
> а без формы это сделать затруднительно
Для таких целей существует DataModule
MsGuns (2011-10-05 17:46:00) [46]Вообще-то положено какбы предварительно логиниться к базе, а без формы это сделать затруднительно. И если возникает ошибка, то сообщать о ее характере, предлагая пользователю попробовать еще раз (например после выяснения у админа новых парметров соединения). Как собсна сделаны все субэдэшные сервисы.
Однако тут как всегда дружно и вдохновенно изобретают велосипед
OW (2011-10-05 17:39:00) [47]ну а чем плохо
все открыть, если все нормально, то и создать форму
если нет - все закрыть "взад" и поругаться
MsGuns (2011-10-05 17:36:00) [48]Тогда формочку-сплитер.
Ega23 (2011-10-05 17:33:00) [49]
> .OnActivate
Вот это как раз не следует. Нафига показывать то, что уже не прошло валидацию?
MsGuns (2011-10-05 17:26:00) [50]А если попробовать выкопать морковку без трактора, комбайна, эскаватора, звена колхозниц и роты пулеметчиков - просто голыми руками:
procedure TForm1.OnActivate(Sender: TObject);
begin
if (Tag>0) then exit;
try
... // Открытие всех нужных таблиц
Tag := 1;
except
ShowMessage('Ошибка открытия') ;
end;
end;
Ega23 (2011-10-05 17:18:00) [51]Если поднять в OnCreate - таки будет, также с обоими вариантами
Ega23 (2011-10-05 17:16:00) [52]
> Игорь Шевченко © (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
Игорь Шевченко (2011-10-05 17:10:00) [53]
> И что же будет показано?
форма
_Юрий (2011-10-05 15:46:00) [54]
> Ega23 © (05.10.11 14:14) [19]
> Только мне всё равно непонятно преимущество вызова исключения
> в конструкторе.
Оно в том, что не нужно совершать дополнительных плясок с try-except или с введением дополнительных методов инициализации
_Юрий (2011-10-05 15:43:00) [55]
> Ega23 © (05.10.11 14:14) [19]
procedure TCustomForm.AfterConstruction;
begin
if not OldCreateOrder then DoCreate;
> Игорь Шевченко © (05.10.11 15:30) [20]
И что же будет показано?
OW (2011-10-05 15:36:00) [56]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:30:00) [57]
> При возникновении исключения форма автоматически разрушится,
> и на экране ничего показано не будет.
будет
Ega23 (2011-10-05 14:14:00) [58]
> или в AfterConstruction, по умолчанию - второе.
Зависит от того, до inherited или после.
Только мне всё равно непонятно преимущество вызова исключения в конструкторе. Не, я в принципе понимаю, что можно, TFileStream и всё такое. Но преимуществ не вижу.
З.Ы. Что-то я туплю уже...
_Юрий (2011-10-05 14:04:00) [59]
> Ega23 © (05.10.11 12:47) [17]
В зависимости от значения OldCreateOrder - или в конструкторе, или в AfterConstruction, по умолчанию - второе.
Можно конечно выставить это свойство в true. Но на мой взгляд, ни к чему завязываться на состояние без необходимости.
Ega23 (2011-10-05 12:47:00) [60]
> В отличие от 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;