Текущий архив: 2004.03.14;
Скачать: CL | DM;
ВнизКак закрять форму еще при её создании Найти похожие ветки
← →
Sphinx (2004-03-02 16:05) [0]Вопрос дурной немного, Но что поделаешь :)
В-общем необходимо в событии OnCreate обработать процедуру открытия файла, жизненно необходимого для работы программы:
try
TIm.Picture.LoadFromFile(FIm);
except
Application.MessageBox("Не удалось загрузить файл *.*", "ОШИБКА", MB_OK);
MainForm.Close;
end;
Так вот, форма при возникновении ошибки не закрывается.
Может подскажите что я не так делаю?
Кстати, если этот код вставить в OnActivate то все работает, но форма на мгновение возникает на экране, что не есть хорошо.
← →
Тимохов (2004-03-02 16:07) [1]В форме переопределите
function HandleCreateException: Boolean; dynamic;
либо
procedure DoCreate; virtual;
← →
Семен Сорокин (2004-03-02 16:08) [2]В зависимости от задачи:
1.
Application.ShowMainForm = false;
2.
PostMessage(self.Handle, CN_RELEASE, 0, 0);
← →
Тимохов (2004-03-02 16:09) [3]Если сделать 1, то исключения будут приводить к прерыванию в создании формы.
Т.е. close не надо - просто надо сгененить исключение.
← →
Petr V. Abramov (2004-03-02 16:24) [4]Тимохов © (02.03.04 16:07) [1]
Одно но: все это имеет смысл, если OldCreateOrder = true, а по умолчанию он (оно? :) - false, DoCreate вместе с HandleCreateException и OnCreate вызывается из AfterConstruction
← →
Тимохов (2004-03-02 16:38) [5]
> Petr V. Abramov © (02.03.04 16:24) [4]
В общем то вы правы, но что это меняет.
ФОрма все равно не создастся.
Что обратили мое внимание на этот факт - спасибо. У меня форма пришла со старого проекта, там это все работало. Посмотрел, у нее действительно OldCreateOrder.
← →
Sphinx (2004-03-02 16:43) [6]
> PostMessage(self.Handle, CN_RELEASE, 0, 0);
С API у меня слабовато (и очень), поэтому меня обругали:
[Error] Main.pas(43): Undeclared identifier: "CN_RELEASE"
что я забыл? ShellAPI указал.
пробовал еще так: SendMessage(Self.Handle, WM_DESTROY, 0, 0);
скомпилировалось, но форма не уничтожилась.
Подменять events или подменять их смысла не вижу (для моей задачи) если не предложат решения по-проще и работающего в onCreate перенесу проверку в OnActivate и сделаю форму по умолчанию невидимой.
← →
Семен Сорокин (2004-03-02 16:46) [7]Sphinx © (02.03.04 16:43) [6]
sorry, ошибся см. CM_RELEASE
← →
Sphinx (2004-03-02 16:51) [8]
> Семен Сорокин © (02.03.04 16:46) [7]
АГРОМНОЕ спасибо :) исправил ошибку - все заработало как надо.
← →
YuRock (2004-03-02 17:12) [9]А еще иногда удобно в таких случаях (если это - главная форма) писать ExitProcess(1) - тогда форма "мигать" не будет :))
← →
Petr V. Abramov (2004-03-02 17:15) [10]> Тимохов © (02.03.04 16:38) [5]
> ФОрма все равно не создастся.
Еще как создастся. Вот только до Show дело не дойдет ( если спецмер типа try.. не предпринять ), и если на нее не сохраняется указатель, так останется где-то за кадром до закрытия приложения. Надо ли уничтожать то, что создали, обсуждать будем? :)
← →
Тимохов (2004-03-02 17:18) [11]
> Petr V. Abramov © (02.03.04 17:15) [10]
Вообще говоря я это проверил. Пойду еще раз проверю, если вы не против. Не уверен (уверен буду минут через 5), но думаю, что форма все-таки не создасться.
← →
Тимохов (2004-03-02 17:25) [12]
> Petr V. Abramov © (02.03.04 17:15) [10]
Посмотрел, вы не правы: до freeinstance и до destroy формы дело доходит. Что останется за кадром?
← →
Тимохов (2004-03-02 17:27) [13]Другой вопрос, что ondestroy не вызывается, т.к. объект не был до конца иницилизирован, то BeforeDestr. не вызывается. Это недостаток, конечно.
← →
Defunct (2004-01-23 13:37) [14]Приведу еще один способ
> В-общем необходимо в событии OnCreate обработать процедуру открытия файла, жизненно необходимого для работы программы:
try
TIm.Picture.LoadFromFile(FIm);
except
Application.MessageBox("Не удалось загрузить файл *.*", "ОШИБКА", MB_OK);
Halt(0);
end;
← →
Defunct (2004-01-23 13:38) [15]Щас мне вспомнят ветку про удаление объектов ;)
← →
Petr V. Abramov (2004-03-03 17:49) [16]> Тимохов © (02.03.04 17:25) [12]
Тогда остается вопрос, что и где и под какой Delphi Вы проверяли.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
// форма с exception на FormCreate
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
raise Exception.Create("Обратитесь к разработчику");
end;
end.
// а из этой ее вызываем
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
fm: TForm;
begin
try
fm := TForm1.Create(Self);
//fm.free
finally
fm.Show
end
end;
end.
//
Нажмите на Form2.Button1 и увидите сначала текст exception, а потом - саму Form1 в прекрасном рабочем состоянии. Если раскомментарить fm.free, вот тогда на fm.Show увидим то, что положено при несозданной форме
D6 W2k
← →
Тимохов (2004-03-03 17:53) [17]
> Petr V. Abramov © (03.03.04 17:49) [16]
Шестой 2к.
← →
Тимохов (2004-03-03 18:13) [18]
> > Petr V. Abramov © (03.03.04 17:49) [16]
Сейчас свой пример прведу
← →
Тимохов (2004-03-03 18:29) [19]> > Petr V. Abramov © (03.03.04 17:49) [16]
Напоминаю суть вопроса. Мое утверждение было, что если переопределить DoCreate, то в случае возникновения ошибки в OnCreate и OldCreateOrder = false форма не создаться. Утверждение Петра Абрамова было, что форма создатся.
Приведенный ниже пример показывает мою правоту - форма не создается, а уничтожается, о чем готоврит вызов метода FreeInstance.
вызываемая форма
OldCreateOrder = false
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm2 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DoCreate; override;
destructor destroy; override;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
procedure FreeInstance; override;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.DoCreate;
begin
if Assigned(OnCreate) then OnCreate(Self);
if fsVisible in FFormState then Visible := True;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
raise Exception.create("error in formcreate");
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
showmessage("1"); // не доходит
end;
procedure tform2.AfterConstruction;
begin
inherited;// доходит
end;
procedure tform2.BeforeDestruction;
begin
inherited;// не доходит
end;
destructor tform2.destroy;
begin
inherited; // доходит
end;
procedure tform2.FreeInstance;
begin
inherited; // доходит
end;
end.
вызывающая форма
procedure TForm1.Button11Click(Sender: TObject);
begin
tform2.create(application).show()
end;
← →
Petr V. Abramov (2004-03-03 18:33) [20]Разница в HandleCreateException - в DoCreate вызов OnCreate стоит в try..except, а поднимать exception или нет, оно (HandleCreateException) и определяет.
Но по-любому, IMHO, проще exception в конструкторе поднять :)
← →
Тимохов (2004-03-03 18:36) [21]
> Petr V. Abramov © (03.03.04 18:33) [20]
Я вообще событиями не пользуюсь - только конструктором и деструктором.
Так что темы для спора нет - я не утверждаю, что надо делать описанным мною способом (сам, правда, так делаю, но это исторически сложилось).
А то, что правду выяснили, это хорошо :))))))))
Страницы: 1 вся ветка
Текущий архив: 2004.03.14;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.013 c