Правильный способ уничтожить форму и показать другую в Delphi
В настоящее время в моей программе есть форма Startup и форма Main. Форма запуска отображается на секунду или две.
Прямо сейчас у меня есть следующий код в таймере:
frmStartup.Destroy;
frmMain := TfrmMain.Create(Self);
frmMain.Show;
Прямо сейчас, я не уверен, что это правильный способ сделать это.. Это работает, но при звонке application.Terminate();
Я получаю сообщение о нарушении прав доступа, заставляя меня поверить, что я что-то не так сделал при уничтожении формы запуска.
Если бы кто-нибудь мог показать правильную процедуру выполнения того, что я хочу (немодально), я был бы очень признателен.
Заранее спасибо,
РЕДАКТИРОВАТЬ:
Спасибо за все отзывы, я исправил нарушения доступа, просто добавив код:
Action := caFree;
В метод frmStartup.formClose.
4 ответа
Не создавайте frmStartup
с помощью Application.CreateForm
, Первая созданная форма становится основной формой вашего приложения, и если это frmStartup
ты разрушаешь это снаружи Application
знания.
Вместо этого используйте обычный Form.Create в исходном файле проекта (.dpr):
var
frmStartup: TfrmStartup;
begin
Application.Initialize;
Application.MainFormOnTaskBar := True;
frmStartup := TfrmStartup.Create(nil); // No owner assigned here!
frmStartup.Show;
frmStartup.Update;
Application.CreateForm(TfrmMain, frmMain); // Let Application have this for main form
// Delay here if needed
frmfrmStartup.Free;
Application.Run;
end.
Возможно, вы захотите, чтобы ваш Splash Screen отображался как можно раньше, поэтому в идеале это следует делать на этапе инициализации, тогда он должен исчезнуть только тогда, когда MainForm будет готова вступить во владение.
Это именно то, что мы делаем в нашем приложении, где мы снова используем диалоговое окно "О программе" в качестве заставки, а затем отпускаем его, когда MainForm захватывает фокус.
В dpr, насколько это возможно в предложении использования после необходимых блоков VCL/RTL:
f_adtDlgAbout in 'f_adtDlgAbout.pas' {frmDlgAbout}, // ASAP to be used as a Splash screen
О блоке (К вашему сведению, FormStyle
является fsStayOnTop
а также Position
является poScreenCenter
):
unit f_adtDlgAbout;
[...]
type
TfrmDlgAbout = class(TForm)
[...]
procedure TfrmDlgAbout.SplashFormDeactivate(Sender: TObject);
begin
Release;
end;
initialization
// Use it as a Splash screen
with TfrmDlgAbout.Create(nil) do begin
AlphaBlend := True;
AlphaBlendValue := 208;
BorderStyle := bsNone;
btnOK.Visible := False;
OnDeactivate := SplashFormDeactivate;
Show;
Update;
end;
end.
TFrmMain.Create(Self)??? Что такое "Я"? Вы делаете это изнутри frmStartup? Если так, не надо. Используйте TFrmMain.Create(NIL).
Используйте frmStartup.Release, чтобы освободить frmStartup, если весь отправленный вами код находится внутри метода frmStartup, вам нужно поместить эту строку внизу метода.
Установите frmMain в качестве основной формы
На frmMain.FormCreate
frmStartup := TfrmStartup.Create(nil);
try
frmStartup.ShowModal;
finally
frmStartup.Free;
end;